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 }
01-08 10:17