pat1001. Battle Over Cities - Hard Version 解题报告

/**
题目:删去一个点,然后求出需要增加最小代价的边集合生成连通图
思路:
prim+最小堆
1.之前图中未破坏的边必用,从而把两两之间可互达的点集合 合并成一个点
2.求出不同点集合的最短距离,用prim+最小堆求出最小生成树

kruskal
1.之前图中未破坏的边必用,全部加到图中
2.途中被破坏的边按照边权从小到大的顺序依次加入图中,直到图变为连通图

两个方法的对应一个点的最小生成树的复杂度都是nlogm,第二个方法较好写

优化:
1.未破坏的边直接加入图中
2.当有n-2条边(当前删去一个点后,图中n-1个点)在图中时,直接结束建生成树

另外:
求图的连通性:
有向 强连通
无向 并查集

当然,并查集好写很多。。。
**/

 

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #define maxn 500
  4 #define maxm 125000
  5 #define maxdist 100000
  6 
  7 /**
  8 题目:删去一个点,然后求出需要增加最小代价的边集合生成连通图
  9 思路:
 10 prim+最小堆
 11 1.之前图中未破坏的边必用,从而把两两之间可互达的点集合 合并成一个点
 12 2.求出不同点集合的最短距离,用prim+最小堆求出最小生成树
 13 
 14 kruskal
 15 1.之前图中未破坏的边必用,全部加到图中
 16 2.途中被破坏的边按照边权从小到大的顺序依次加入图中,直到图变为连通图
 17 
 18 两个方法的对应一个点的最小生成树的复杂度都是nlogm,第二个方法较好写
 19 
 20 优化:
 21 1.未破坏的边直接加入图中
 22 2.当有n-2条边(当前删去一个点后,图中n-1个点)在图中时,直接结束建生成树
 23 
 24 另外:
 25 求图的连通性:
 26 有向 强连通
 27 无向 并查集
 28 
 29 当然,并查集好写很多。。。
 30 **/
 31 
 32 struct node
 33 {
 34     long x,y,c,s;
 35 }edge0[maxm+1],edge1[maxm+1];
 36 long fa[maxn+1];
 37 
 38 long max(long a,long b)
 39 {
 40     if (a>b)
 41         return a;
 42     else
 43         return b;
 44 }
 45 
 46 int cmp(const void *a,const void *b)
 47 {
 48     //先把未损坏的路径加入图中
 49     if ((*(struct node *)a).s < (*(struct node *)b).s)
 50         return 1;
 51     else if ((*(struct node *)a).s > (*(struct node *)b).s)
 52         return -1;
 53     //再对已损坏的路径进行排序,用kruskal算法,m log m
 54     else if ((*(struct node *)a).c < (*(struct node *)b).c)
 55         return 1;
 56     else
 57         return -1;
 58 }
 59 
 60 long getfather(long d)
 61 {
 62     if (fa[d]==d)
 63         return d;
 64     else
 65         return getfather(fa[d]);
 66 }
 67 
 68 int main()
 69 {
 70     long i,j,n,m,p,q,x,y,c,s,g,fx,fy,ans,cost[maxn+1];
 71     while (scanf("%ld%ld",&n,&m)!=EOF)
 72     {
 73         p=0;
 74         q=0;
 75         for (i=0;i<m;i++)
 76         {
 77             scanf("%ld%ld%ld%ld",&x,&y,&c,&s);
 78             if (s==1)
 79             {
 80                 p++;
 81                 edge1[p].x=x; edge1[p].y=y; edge1[p].c=c; edge1[p].s=s;
 82             }
 83             else
 84             {
 85                 q++;
 86                 edge0[q].x=x; edge0[q].y=y; edge0[q].c=c; edge0[q].s=s;
 87             }
 88         }
 89         qsort(edge0+1,q,sizeof(struct node),cmp);
 90 
 91         ans=0;
 92         for (i=1;i<=n;i++)
 93         {
 94             for (j=1;j<=n;j++)
 95                 fa[j]=j;
 96             g=0;
 97             //edge - exist
 98             for (j=1;j<=p;j++)
 99             {
100                 if (edge1[j].x==i || edge1[j].y==i) continue;
101                 fx=getfather(edge1[j].x);
102                 fy=getfather(edge1[j].y);
103                 if (fx==fy) continue;
104                 fa[fx]=fy;
105                 g++;
106                 if (g==n-2)
107                     break;
108             }
109             //优化
110             if (g==n-2)
111             {
112                 cost[i]=0;
113                 continue;
114             }
115 
116             //edge - not exist
117             cost[i]=0;
118             for (j=1;j<=q;j++)
119             {
120                 if (edge0[j].x==i || edge0[j].y==i) continue;
121                 fx=getfather(edge0[j].x);
122                 fy=getfather(edge0[j].y);
123                 if (fx==fy) continue;
124                 fa[fx]=fy;
125                 g++;
126                 cost[i]+=edge0[j].c;
127                 //优化
128                 if (g==n-2)
129                     break;
130             }
131             if (g<n-2)
132                 cost[i]=maxdist;
133             ans=max(ans,cost[i]);
134         }
135         if (ans>0)
136         {
137             for (i=1;i<=n;i++)
138                 if (cost[i]==ans)
139                 {
140                     printf("%ld",i);
141                     break;
142                 }
143             for (j=i+1;j<=n;j++)
144                 if (cost[j]==ans)
145                     printf(" %ld",j);
146             printf("\n");
147         }
148         else
149             printf("0\n");
150     }
151     return 0;
152 }

 

 

 

posted @ 2017-07-15 02:13  congmingyige  阅读(1764)  评论(0编辑  收藏  举报