http://acm.hdu.edu.cn/showproblem.php?pid=1598
题意:中文的就不说了。
分析:题目要求从起点到终点的最大值与最小值的差最小,第一感觉是floyd,但是要保存经过的每条边,这就卡住了。后来发现从起点到终点也可以用并查集做,想想从起点到终点肯定要属于同一个集合,这就行了。其实这题就是用的kruskal的思想。具体看代码。
还有一个地方我觉得很奇怪为什么下面两个union会得到的结果不一样,第一个ac,第二个Runtime Error(ACCESS_VIOLATION)
View Code
void Union(int R1,int R2){ int r1=findset(R1), r2=findset(R2); if(r1!=r2){ pa[r2]=r1; } //int tmp=pa[r1]+pa[r2];//为什么这个就Runtime Error(ACCESS_VIOLATION) // if(pa[r1]>pa[r2]){ // pa[r1]=r2; // pa[r2]=tmp; // } // else { // pa[r2]=r1; // pa[r1]=tmp; // } }
View Code
// I'm lanjiangzhou //C #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <math.h> #include <time.h> //C++ #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <cctype> #include <stack> #include <string> #include <list> #include <queue> #include <map> #include <vector> #include <deque> #include <set> using namespace std; //*************************OUTPUT************************* #ifdef WIN32 #define INT64 "%I64d" #define UINT64 "%I64u" #else #define INT64 "%lld" #define UINT64 "%llu" #endif //**************************CONSTANT*********************** #define INF 0x3f3f3f3f // aply for the memory of the stack //#pragma comment (linker, "/STACK:1024000000,1024000000") //end const int maxn = 2010; struct edge{ int u,v,w; }edges[maxn]; int pa[maxn]; int n,m; int start,end; //int cmp(const void*a,const void*b){//从小到大排序 // edge aa=*(const edge*)a; // edge bb=*(const edge*)b; // return aa.w-bb.w; //} int cmp1(const edge &p,const edge &q){ return p.w<q.w; } void UFset(){ for(int i=1;i<=n;i++){ pa[i]=-1; } } int findset(int x){ int s; for(s=x;pa[s]>=0;s=pa[s]); while(s!=x){ int tmp=pa[x]; pa[x]=s; x=tmp; } return s; } void Union(int R1,int R2){ int r1=findset(R1), r2=findset(R2); // if(r1!=r2){ // pa[r2]=r1; // } int tmp=pa[r1]+pa[r2]; if(pa[r1]>pa[r2]){ pa[r1]=r2; pa[r2]=tmp; } else { pa[r2]=r1; pa[r1]=tmp; } } int main(){ int t; while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=m;i++){ scanf("%d%d%d",&edges[i].u,&edges[i].v,&edges[i].w); } sort(edges+1,edges+1+m,cmp1); // qsort(edges+1,m+1,sizeof(edges[0]),cmp); scanf("%d",&t); while(t--){ scanf("%d%d",&start,&end); int mindiff=INF; int u,v; for(int i=1;i<=m;i++){ UFset(); for(int j=i;j<=m;j++){ u=edges[j].u; v=edges[j].v; Union(u,v); if(findset(start)==findset(end)){ int ans=edges[j].w-edges[i].w; if(ans<mindiff){ mindiff=ans; // break; } break; } } } if(mindiff==INF) printf("-1\n"); else printf("%d\n",mindiff); } } return 0; }