[51nod1640] 天气晴朗的魔法
2016-11-16 09:02
381 查看
题目链接
题解:题目描述非常excited。显然,二分可以搞(因为没开long long和没写读优又T又WA了n次),最后用读优卡过去了。不过,只需要先kruskal一次求最小生成树(条件1,最大边权尽量小),记录生成最大边权MX,再以MX为最大边权跑最大生成树就行了(条件2,权值和尽量大),比二分不知道高到那里去了
题解:题目描述非常excited。显然,二分可以搞(因为没开long long和没写读优又T又WA了n次),最后用读优卡过去了。不过,只需要先kruskal一次求最小生成树(条件1,最大边权尽量小),记录生成最大边权MX,再以MX为最大边权跑最大生成树就行了(条件2,权值和尽量大),比二分不知道高到那里去了
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <climits> using namespace std; const int M=100005; #define INF LLONG_MAX/100000 #define ll long long int t=1,n,m; ll l,r,mid,ans,sum; struct edge{ int u,v,val; }e[M*3]; int f[M]; ll read(){ char c=getchar();ll x=0,f=1; while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') x=(x*10)+c-48,c=getchar(); return x*f; } int fd(int x){ return f[x]==x?x:f[x]=fd(f[x]); } bool cmp(edge a,edge b){ return a.val>b.val; } bool ok(ll x) { int tot=0;sum=0; for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=m;i++) { if(e[i].val>x) continue; int x=fd(e[i].u),y=fd(e[i].v); if(x!=y){ f[x]=y;tot++; sum+=e[i].val; } } return tot==n-1; } void init() { cin>>n>>m; for(int i=1;i<=m;i++) e[i].u=read(),e[i].v=read(),e[i].val=read(); sort(e+1,e+1+m,cmp); } void work() { l=0,r=INF; while(l<=r) { mid=(l+r)>>1; if(ok(mid)) ans=sum,r=mid-1; else l=mid+1; } printf("%lld\n",ans); } int main() { init(); work(); return 0; }
相关文章推荐
- 51nod1640-最小生成树&二分|性质-天气晴朗的魔法
- 51Nod - 1640 天气晴朗的魔法
- 51nod 1640 天气晴朗的魔法 克鲁斯卡尔
- 51nod 1640 天气晴朗的魔法
- 51nod 1640 天气晴朗的魔法(并查集)
- 51Nod-1640-天气晴朗的魔法
- 51nod 1640 天气晴朗的魔法(最小生成树)
- 51nod 1640 天气晴朗的魔法
- 51nod 1640 天气晴朗的魔法 二分 + 克鲁斯卡算法(kruskal算法) 做复杂了
- nod-1640-天气晴朗的魔法
- 51nod 1640 天气晴朗的魔法 最小生成树
- 51nod 1640天气晴朗的魔法(克鲁斯卡尔,并查集)
- 51nod-1640--天气晴朗的魔法(简单最小生成树)
- 天气晴朗的魔法(图论)
- 51nod 1640 天气晴朗的魔法
- 1640 天气晴朗的魔法
- 51nod 1640 天气晴朗的魔法 最小生成树
- 天气晴朗的魔法
- 51NOD 1640 天气晴朗的魔法(二分+最大生成树)
- 51nod 1640 天气晴朗的魔法 【二分枚举最大生成树】or【最小&&最大 生成树】