思路:
首先如果想到了Kruskal算法,那么下一步我们可能马上会想:那我们就从头开始写这个算法吧。然后一写就很容易发现一个问题——如果按照正常的Kruskal算法来做,那么start到end的舒适度中的那个“最小边”就只能是所有边中最小的那个,而这是明显不符合逻辑的事情,所以我们就会接着想,如果不是这个最小边,那它会是哪个边——当然是更大的边了,于是我们便开始按照从小到大的顺序去依次遍历所有的边长,这是外层的for循环;然后对于内层的for循环呢,就是根据这个题目的要求来了,由于我们要求舒适度最高的,因此这一路下来我们再往上加边的时候一定是要尽量在现有的min的基础上尽量减小max的值,从而实现max-min最小。
AC代码:
#include#include #include #define maxn 207 #define INF 9999999 using namespace std; int n,m; int father[maxn]; int s[maxn]; struct edge{ int s; int e; int w; }; int set_same(int x,int y) { int i,j; for(i = x;i != father[i];i = father[i]) father[i] = father[father[i]]; for(j = y;j != father[j];j = father[j]) father[j] = father[father[j]]; return i==j?1:0; } void set_union(int x,int y) { int i,j; for(i = x;i != father[i];i = father[i]) father[i] = father[father[i]]; for(j = y;j != father[j];j = father[j]) father[j] = father[father[j]]; if(s[i] < s[j]) { father[i] = j; s[i] += s[j]; } else { father[j] = i; s[j] += s[i]; } } int set_find(int x) { int i; for(i = x;i != father[i];i = father[i]) father[i] = father[father[i]]; return i; } void set_init() { for(int i = 1;i <= n;i++){ father[i] = i; s[i] = 1; } } void Kruskal(int S,int E) { int dmax,dmin; } bool cmp(edge a,edge b) { return a.w<b.w; } int main() { int i,j; edge edges[1007]; while(cin>>n>>m) { for(i = 1;i <= m;i++) cin>>edges[i].s>>edges[i].e>>edges[i].w; sort(edges+1,edges+1+m,cmp); int cast; cin>>cast; int S,E; while(cast--) { cin>>S>>E; int ans = INF; for(i = 1;i <= m;i++) { set_init(); for(j = i;j <= m;j++) { int A = edges[j].s; int B = edges[j].e; set_union(A,B); if(set_same(S,E)) { ans = min(ans,edges[j].w-edges[i].w); break; } } if(j == m) break; } if(ans == INF) cout<<"-1"<<endl; else cout< endl; } } return 0; }