poj2831生成树

链接:http://poj.org/problem?id=2831

题意:给出一些边,再对这些边进行修改(只允许边权值减小),问该边修改之后是否可能是最小生成树上的边。

思路:用prime算法求最小生成树,边求边计算出从s到t之间最长的边。然后询问时候,看这条边和s到t之间的最长的边比较大小就可以了~

一开始想的很麻烦~

View Code
 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  }

 

posted @ 2013-04-12 21:09  _sunshine  阅读(320)  评论(0编辑  收藏  举报