bzoj1050: [HAOI2006]旅行comf(最小生成树)
2017-10-27 21:30
155 查看
题目传送门
想了一个多小时就想到一个暴力,结果还真是。。
解法:
先判断st和ed连不连通,不连通就IMPOSSIBLE。
最小生成树可以做。
先按照边权从小到大排序。
然后枚举每条边,以当前这条边作为最小的边,添加比它大的边。
如果添加的边可以使得st和ed连通,那么维护一下答案。
那如果最大的边不一定是st到ed这条路径上面的边怎么办呢。
对于每一条边,添加完之后马上判断st和ed是否连通。
如果这条边添加完后st和ed连通了。
说明这条边肯定在st到ed上。
而又因为这条边是最后一个添加的(边权从小到大),所以这条边肯定是这种方法的最大值。
本想加个优化结果WA了不懂。
路过dalao帮忙看看呗。
代码实现:
想了一个多小时就想到一个暴力,结果还真是。。
解法:
先判断st和ed连不连通,不连通就IMPOSSIBLE。
最小生成树可以做。
先按照边权从小到大排序。
然后枚举每条边,以当前这条边作为最小的边,添加比它大的边。
如果添加的边可以使得st和ed连通,那么维护一下答案。
那如果最大的边不一定是st到ed这条路径上面的边怎么办呢。
对于每一条边,添加完之后马上判断st和ed是否连通。
如果这条边添加完后st和ed连通了。
说明这条边肯定在st到ed上。
而又因为这条边是最后一个添加的(边权从小到大),所以这条边肯定是这种方法的最大值。
本想加个优化结果WA了不懂。
路过dalao帮忙看看呗。
代码实现:
#include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; int gcd(int a,int b) { if(a==0) return b; return gcd(b%a,a); } struct node { int x,y,c; }a[5100];int len; void ins(int x,int y,int c) { len++; a[len].x=x;a[len].y=y;a[len].c=c; } bool cmp(node n1,node n2) { return n1.c<n2.c; } int fa[510]; int findfa(int x) { if(x!=fa[x]) fa[x]=findfa(fa[x]); return fa[x]; } int main() { //freopen("1050.in","r",stdin); //freopen("1050.out","w",stdout); int n,m;scanf("%d%d",&n,&m); len=0; for(int i=1;i<=m;i++) { int x,y,c;scanf("%d%d%d",&x,&y,&c); if(x!=y) ins(x,y,c); } int st,ed;scanf("%d%d",&st,&ed); for(int i=1;i<=n;i++) fa[i]=i; int t=0; sort(a+1,a+1+len,cmp); for(int i=1;i<=len;i++) { int xx=findfa(a[i].x),yy=findfa(a[i].y); if(xx!=yy) { fa[xx]=yy; t++; if(findfa(st)==findfa(ed)) break; } } if(findfa(st)!=findfa(ed)) { printf("IMPOSSIBLE\n"); return 0; } double ans=999999999.0; int aa,bb; for(int i=1;i<=len;i++) { for(int j=1;j<=n;j++) fa[j]=j; int mx=0; for(int j=i;j<=len;j++) { int xx=findfa(a[j].x),yy=findfa(a[j].y); if(xx!=yy) fa[xx]=yy; /*if(double(a[j].c)/double(a[i].c)>ans) break;*/ //这句优化有任何问题? if(findfa(st)==findfa(ed)) { mx=a[j].c; break; } } if(findfa(st)!=findfa(ed)) break; if(ans>double(mx)/double(a[i].c)&&findfa(st)==findfa(ed)) { ans=double(mx)/double(a[i].c); aa=mx;bb=a[i].c; } } int d=gcd(aa,bb); aa/=d;bb/=d; if(bb==1) printf("%d\n",aa); else printf("%d/%d\n",aa,bb); return 0; }
相关文章推荐
- bzoj 1050: [HAOI2006]旅行comf(最小生成树+并查集)
- 【BZOJ 1050】 【HAOI 2006】旅行comf(最小生成树枚举)
- bzoj 1050 [HAOI2006]旅行comf [最小生成树] [动点spfa] [LCT]
- bzoj 1050 [HAOI2006]旅行comf (最小生成树)
- 【bzoj1050】 HAOI2006旅行comf 最小生成树
- bzoj1050 [HAOI2006]旅行comf
- bzoj1050: [HAOI2006]旅行comf
- bzoj1050: [HAOI2006]旅行comf
- bzoj1050: [HAOI2006]旅行comf
- BZOJ1050(HAOI2006)[旅行comf]--并查集
- BZOJ1050 HAOI2006旅行(最小生成树+动态树)
- bzoj1050【HAOI2006】旅行comf
- bzoj1050: [HAOI2006]旅行comf
- BZOJ 2429: [HAOI2006]聪明的猴子|最小生成树kruskal
- BZOJ 1050 [HAOI2006]旅行comf
- BZOJ 1050: [HAOI2006]旅行comf (并查集 或 单调队列)
- BZOJ 2429 [HAOI2006]聪明的猴子 MST最小生成树
- bzoj 1050: [HAOI2006]旅行comf
- bzoj 1050: [HAOI2006]旅行comf(尺取+最短路)
- BZOJ1050 [HAOI2006]旅行comf