P2196 挖地雷
题解
其实这道题是可以Floyd跑最长路的,但是注意一个问题就是dis数组要初始化负无穷,两个点之间不能相互到达一定要初始化dis数组为负无穷!!!敲黑板
当一条路不能走的时候,要把这条路赋成负无穷,不能赋成0,因为如果这条路走完后面的路权值和更大的话还是会选上这条路。(Orz Fusu)
代码
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<string> 6 #include<cstring> 7 #include<queue> 8 #include<cstdlib> 9 10 using namespace std; 11 12 typedef long long ll; 13 14 inline int read(){ 15 int ans=0; 16 char last=' ',ch=getchar(); 17 while(ch<'0'||ch>'9') last=ch,ch=getchar(); 18 while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar(); 19 if(last=='-') ans=-ans; 20 return ans; 21 } 22 23 int n; 24 int a[25]; 25 int f[25][25]; 26 int path[25][25]; 27 int s=0,t=0,maxx=-63; 28 29 int main() 30 { 31 n=read(); 32 memset(f,-63,sizeof(f)); 33 for(int i=1;i<=n;i++) a[i]=read(),f[i][i]=a[i]; 34 35 for(int i=1;i<n;i++) 36 for(int j=i+1;j<=n;j++){ 37 int x=read(); 38 if(x) f[i][j]=a[i]+a[j]; 39 } 40 41 for(int i=1;i<=n;i++) 42 for(int j=1;j<=n;j++) 43 path[i][j]=j; 44 45 for(int k=1;k<=n;k++) 46 for(int i=1;i<=n;i++) 47 for(int j=1;j<=n;j++){ 48 if((f[i][j]<f[i][k]+f[k][j]-a[k])){ 49 f[i][j]=f[i][k]+f[k][j]-a[k]; 50 path[i][j]=path[i][k]; 51 } 52 if(f[i][j]>maxx){ 53 s=i;t=j; 54 maxx=f[i][j]; 55 } 56 } 57 58 while(s!=t){ 59 printf("%d ",s); 60 s=path[s][t]; 61 } 62 printf("%d\n",t); 63 printf("%d\n",maxx); 64 return 0; 65 }