poj 2831 次小生成树模板

/*次小生成树
题意:给你一些路径,现在将一部分路径权值减少后问是否可以替代最小生成树里面的边。
解:次小生成树,即将这条边连上,构成一个环
求出任意两点路径之间的除了这条边的最大值,比较这个最大值>=这条边,说明可以替换。
prime算法次小生成树模板
*/
#include<stdio.h>
#include<string.h>
#define N 1100
#define inf 0x3fffffff
int ma[N][N];
int Min(int a,int b) {
return a>b?b:a;
}
int Max(int a,int b) {
return a>b?a:b;
}
struct node {
int u,v,w;
}bian[N*100];
int maxd[N][N],n;
void prime() {
  int i,j,dis[N],vis[N],pre[N],stac[N],top=0;
  memset(maxd,-1,sizeof(maxd));
  for(i=1;i<=n;i++) {//初始化
    dis[i]=ma[1][i];
    pre[i]=1;
  }
  stac[top++]=1;//储存最小生成树的点
  memset(vis,0,sizeof(vis));
  vis[1]=1;
  for(i=1;i<n;i++) {
  int minn=inf,next=1;
  for(j=1;j<=n;j++)
  if(!vis[j]&&minn>dis[j]) {//找到最近的
    minn=dis[j];
    next=j;
  }
  vis[next]=1;
  //printf("%d\n",minn);
  for(j=0;j<top;j++)
    maxd[next][stac[j]]=maxd[stac[j]][next]=Max(minn,maxd[pre[next]][stac[j]]);//当前点与栈里面的点的最大值为minn和他的父节点与其他点的权值最大值
   stac[top++]=next;//加入栈
    for(j=1;j<=n;j++)
    if(!vis[j]&&dis[j]>ma[next][j]) {//更新距离
        pre[j]=next;//与j连接的最近的点即为他的父节点
        dis[j]=ma[next][j];
    }
  }
  return ;
}
int main(){
   int m,i,j,a,b,c,q;
   while(scanf("%d%d%d",&n,&m,&q)!=EOF) {
     for(i=1;i<=n;i++) {
            ma[i][i]=0;
        for(j=i+1;j<=n;j++)
          ma[i][j]=ma[j][i]=inf;
     }
     for(i=0;i<m;i++) {
        scanf("%d%d%d",&a,&b,&c);
        ma[a][b]=ma[b][a]=Min(ma[a][b],c);//
       // printf("%d\n",ma[a][b]);
        bian[i+1].u=a;bian[i+1].v=b;
        bian[i+1].w=c;
     }
     prime();
     while(q--) {
        scanf("%d%d",&a,&b);
      //  printf("%d\n",maxd[bian[a].u][bian[a].v]);
        if(maxd[bian[a].u][bian[a].v]>=b)//比较即可
            printf("Yes\n");
        else
            printf("No\n");
     }
   }
return 0;
}

poj 2831 次小生成树模板

时间: 2024-10-09 17:57:16

poj 2831 次小生成树模板的相关文章

poj 2831(次小生成树)

题意:给你一幅图,再给你Q个询问,每个询问为id cost,即如果将id这条边的边权改为cost的话,这条边是否可能是最小生成树中的一条边 解题思路:将第i条边(u,v)的权值修改的话,要判断是否是最小生成树中的一条边,首先要把它加入进去,此时必定会引起原来的生成树成环,所以必定要擦去一条边,擦去的是哪一条边,这就利用到了次小生成树的原理了. 之前写过一个次小生成树的题,现在回过头看,感觉又有点不对了. 这里再总结一次: 首先肯定是构造一颗最小生成树,接下来就是枚举不在生成树里的边,假定为(u,

POJ_1679_The Unique MST(次小生成树模板)

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 23942   Accepted: 8492 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undire

POJ 1679 次小生成树

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 30015   Accepted: 10738 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undir

The Unique MST POJ - 1679 (次小生成树)

Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V', E'), with the following properties

The Unique MST POJ - 1679 次小生成树prim

求次小生成树思路: 先把最小生成树求出来  用一个Max[i][j] 数组把  i点到j 点的道路中 权值最大的那个记录下来 used数组记录该条边有没有被最小生成树使用过   把没有使用过的一条边加入最小生成树必然回形成一条回路   在这条回路中减去 除加入的边的权值最大的一条边  原图必然保持连通  (如果此时 权值最大的边和新加入的边权值相同  则存在 不同的最小生成树) 把每一条边加入再删除后 即可得出次小生成树 参考了: https://blog.csdn.net/qq_3395144

次小生成树模板

1 kruskal 2 #include <vector> 3 #include <iostream> 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #define INF 0x3f3f3f3f 8 9 using namespace std; 10 int n,m; 11 struct data 12 { 13 int u,v,w; 14 bool vis;

uva10600次小生成树模板题

裸题,上模板就行,注意j  !  =  k #include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cassert> #include<iomanip> #include<cstdlib> #include&

POJ 1679 prime次小生成树判定生成树是否唯一

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 21931   Accepted: 7784 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undire

洛谷 P4180 【模板】严格次小生成树[BJWC2010]【次小生成树】

严格次小生成树模板 算法流程: 先用克鲁斯卡尔求最小生成树,然后给这个最小生成树树剖一下,维护边权转点权,维护最大值和严格次大值. 然后枚举没有被选入最小生成树的边,在最小生成树上查一下这条边的两端点的路径上的最长边,如果最长边等于枚举到的边的边权,那么选次长边(没有次长边的话直接跳过),然后在最小生成树的权值上减去路径上最/次长边,加上当前枚举的边的边权 因为如果加入枚举的边的,那么就形成了一个环,需要断开一条边 注意一开始单点次小值赋为0 #include<iostream> #inclu