成都网赛1004 &hdu4034

哎,郁闷 比赛时,WA了n多次,最终也没过,以为算法错了,可想来想去感觉没错啊!以给的最短距离为边建图,然后利用floyd算所有点之间的距离,如果i到j的距离经过k则标记i到j,最后如果i到j被标记了并且求的的最短距离等于原始的(即直连的)则可以把直连的删除即总边数减一。如果求的的距离小于直连标记 输出impossible。    原来是n个点的总边数m应该为n*(n-1); 当时不知道怎么搞成了m=2*n。

View Code
 1 #include <iostream>
2 #include<cstring>
3 #include<cstdio>
4 using namespace std;
5 int map[105][105];
6 int dist[105][105];
7 int aa[105][105];
8 int n;
9 void ford()
10 {
11 int i,j,k;
12
13 for (i=1;i<=n;i++)
14 for(j=1;j<=n;j++)
15 for(k=1;k<=n;k++)
16 {
17 if(j!=i&&i!=k&&dist[j][k]>=dist[j][i]+dist[i][k])
18 {
19 aa[j][k]=1;
20 dist[j][k]=dist[j][i]+dist[i][k];
21 }
22 }
23 }
24 int main()
25 {
26 int k,i,j,m,ll,gg=0;
27 cin>>k;
28 while (k--)
29 {
30 gg++;
31 memset(map,0,sizeof(map));
32 memset(dist,0,sizeof(dist));
33 memset(aa,0,sizeof(aa));
34 cin>>n;
35 for (i=1;i<=n;i++)
36 for(j=1;j<=n;j++)
37 {
38 cin>>map[i][j];
39 dist[i][j]=map[i][j];
40 }
41 m=n*(n-1);
42 ford();
43 int flag=0;
44 ll=0;
45 for (i=1;i<=n;i++)
46 for(j=1;j<=n;j++)
47 {
48
49 if(dist[i][j]==map[i][j]&&aa[i][j])
50 m--;
51 else{
52 if(dist[i][j]<map[i][j])
53 flag=1;
54
55 }
56 }
57 if(flag||m<n-1) cout<<"Case "<<gg<<": "<<"impossible"<<endl;
58 else{
59
60 cout<<"Case "<<gg<<": "<<m<<endl;
61 }
62 }
63 return 0;
64 }
posted @ 2011-09-11 21:39  我们一直在努力  阅读(214)  评论(1编辑  收藏  举报