poj2831生成树
链接:http://poj.org/problem?id=2831
题意:给出一些边,再对这些边进行修改(只允许边权值减小),问该边修改之后是否可能是最小生成树上的边。
思路:用prime算法求最小生成树,边求边计算出从s到t之间最长的边。然后询问时候,看这条边和s到t之间的最长的边比较大小就可以了~
一开始想的很麻烦~
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <string.h> 3 const int N=1005; 4 const int inf=100000000; 5 int map[N][N],n; 6 int mx[N][N]; 7 int vis[N]; 8 int pre[N]; 9 int dis[N]; 10 struct node{ 11 int s,t; 12 }edge[N*100]; 13 int max(int a,int b){return a>b?a:b;} 14 int min(int a,int b){return a<b?a:b;} 15 void Prime(){ 16 int i,j,t,loc; 17 memset(vis,0,sizeof(vis)); 18 memset(mx,0,sizeof(mx)); 19 for(i=1;i<=n;i++){ 20 dis[i]=inf; 21 } 22 dis[1]=0;loc=1;vis[1]=1; 23 for(i=1;i<n;i++){ 24 for(j=1;j<=n;j++){ 25 if(!vis[j]&&map[loc][j]<dis[j]){ 26 dis[j]=map[loc][j],pre[j]=loc; 27 } 28 } 29 int min=inf; 30 for(j=1;j<=n;j++){ 31 if(!vis[j]&&dis[j]<min) min=dis[loc=j]; 32 } 33 for(j=1;j<=n;j++) if(vis[j]){ 34 mx[loc][j]=max(mx[j][pre[loc]],dis[loc]); 35 mx[j][loc]=mx[loc][j]; 36 } 37 vis[loc]=1; 38 } 39 } 40 int main(){ 41 int m,q,a,b,c; 42 while(scanf("%d%d%d",&n,&m,&q)!=EOF){ 43 for(int i=1;i<=n;i++){ 44 for(int j=1;j<=n;j++){ 45 map[i][j]=inf; 46 } 47 } 48 for(int i=1;i<=n;i++) map[i][i]=0; 49 50 for(int i=1;i<=m;i++){ 51 scanf("%d%d%d",&a,&b,&c); 52 edge[i].s=a;edge[i].t=b; 53 map[a][b]=map[b][a]=min(c,map[a][b]); 54 } 55 Prime(); 56 while(q--){ 57 scanf("%d%d",&a,&b); 58 printf("%s\n",mx[edge[a].s][edge[a].t]>=b?"Yes":"No"); 59 } 60 } 61 return 0; 62 }