HDU 6081 度度熊的王国战略 堆优化Stoer-Wagner算法
来源:互联网 发布:舆情软件销售招聘 编辑:程序博客网 时间:2024/06/05 02:30
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=6081
题意:
Problem Description
度度熊国王率领着喵哈哈族的勇士,准备进攻哗啦啦族。
哗啦啦族是一个强悍的民族,里面有充满智慧的谋士,拥有无穷力量的战士。
所以这一场战争,将会十分艰难。
为了更好的进攻哗啦啦族,度度熊决定首先应该从内部瓦解哗啦啦族。
第一步就是应该使得哗啦啦族内部不能同心齐力,需要内部有间隙。
哗啦啦族一共有n个将领,他们一共有m个强关系,摧毁每一个强关系都需要一定的代价。
现在度度熊命令你需要摧毁一些强关系,使得内部的将领,不能通过这些强关系,连成一个完整的连通块,以保证战争的顺利进行。
请问最少应该付出多少的代价。
思路:
从题意上看,明显是全局最小割,但是由于数据的原因,可以水过去,贴个堆优化stoer-wagner算法模板,记录一下。代码参考自:http://www.cnblogs.com/oyking/p/7340753.html
//复杂度(nmlogm),因此适合稀疏图,稠密图直接用没有堆优化的算法//点下标从1开始#include <bits/stdc++.h>using namespace std;typedef pair<int, int> pii;const int N = 3000 + 10, M = 20000 + 10, INF = 0x3f3f3f3f;struct edge{ int to, cost, next;}g[M];int cnt, head[N], link[N];//link类似于链表int par[N];int dis[N];//dis数组用来表示该点与A集合中所有点之间的边的长度之和bool vis[N];//用来标记是否该点加入了A集合 void init(int n){ for(int i = 1; i <= n; i++) par[i] = i;}void add_edge(int v, int u, int cost){ g[cnt].to = u, g[cnt].cost = cost, g[cnt].next = head[v], head[v] = cnt++;}int ser(int x){ int r = x, i = x, j; while(r != par[r]) r = par[r]; while(par[i] != r) j = par[i], par[i] = r, i = j; return r;}void unite(int x, int y){//把y合并到x中,反过来也对 int p = x; while(~ link[p]) p = link[p]; link[p] = y; par[y] = x;}int min_cut_phase(int n, int &s, int &t){ memset(vis, 0, sizeof vis); memset(dis, 0, sizeof dis); priority_queue<pii> que; t = 1; while(--n) { vis[s = t] = true; for(int i = s; ~i; i = link[i])//更新dis数组,把合并到s中的点全部取出来 for(int j = head[i]; ~j; j = g[j].next) { int v = ser(g[j].to);//g[j].to可能已经合并到其他点上了 if(! vis[v]) que.push(make_pair(dis[v] += g[j].cost, v)); } t = 0; while(! t) { if(que.empty()) return 0; //图不联通 pii p = que.top(); que.pop(); if(dis[p.second] == p.first) t = p.second; } } return dis[t];}int stoer_wagner(int n){ int ans = INF, s, t; for(int i = n; i > 1; i--) { ans = min(ans, min_cut_phase(i, s, t)); if(ans == 0) break; unite(s, t); } return ans;}int main(){ int n, m; while(~ scanf("%d%d", &n, &m)) { init(n); cnt = 0; memset(head, -1, sizeof head); memset(link, -1, sizeof link); int a, b, c; for(int i = 1; i <= m; i++) { scanf("%d%d%d", &a, &b, &c); add_edge(a, b, c), add_edge(b, a, c); } printf("%d\n", stoer_wagner(n)); } return 0;}
另外一个模板(没看懂):
#include <bits/stdc++.h>//#include <ext/pb_ds/priority_queue.hpp>#define rep(i,n) for(int i=1;i<=n;++i)#define inf 0x3f3f3f3f#define M 100005#define N 3005using namespace std;//__gnu_pbds::priority_queue<int> q;struct Eedge{ int x,y,w;} e[M];struct edge{ int v,c,f;} ee[2][M];struct node{ int len,pos;};int operator <(const node &a,const node &b){ return a.len<b.len;}int cmp(Eedge x,Eedge y){ if(x.x==y.x)return x.y<y.y; return x.x<y.x;}int b[2][N],d[N];priority_queue<node> q;int n,m,ans,x,y,z,tot[2],top,tp,ts,tr;bool f[N],r;int tab[N];void adds(bool p,int x,int y,int w){ ee[p][++tot[p]]=(edge) { y,w,b[p][x] }; b[p][x]=tot[p];}void add(bool p,int x,int y,int w){ adds(p,x,y,w); adds(p,y,x,w);}int main(){ while(scanf("%d%d",&n,&m)==2) { memset(b,0,sizeof b); tot[0]=tot[1]=0; ans=inf; rep(i,m) { scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w); if(e[i].x>e[i].y)swap(e[i].x,e[i].y); } sort(e+1,e+m+1,cmp); top=0; rep(i,m)if(e[top].x!=e[i].x||e[top].y!=e[i].y)e[++top]=e[i]; else e[top].w+=e[i].w; m=top; rep(i,m)if(e[i].x!=e[i].y)add(0,e[i].x,e[i].y,e[i].w); r=0; rep(zz,min(n-1,max(400,n/2-1))) { memset(d,0,sizeof d); memset(f,0,sizeof f); d[1]=inf; q.push((node) { d[1],1 }); tp=0; while(!q.empty()) { x=q.top().pos; q.pop(); if(f[x])continue; for(int i=b[r][x]; i; i=ee[r][i].f) { int v=ee[r][i].v; if(!f[v])d[v]+=ee[r][i].c,q.push((node){d[v],v}); } f[x]=1; ++tp; if(tp==n-zz+1)ts=x; if(tp==n-zz)tr=x; } tp=0; for(int i=b[r][ts]; i; i=ee[r][i].f)tp+=ee[r][i].c; r^=1; ans=min(ans,tp); memset(b[r],0,sizeof b[r]); tot[r]=0; rep(i,n)if(i!=tr&&i!=ts) { for(int j=b[r^1][i]; j; j=ee[r^1][j].f) if(ee[r^1][j].v!=tr&&ee[r^1][j].v!=ts)adds(r,i,ee[r^1][j].v,ee[r^1][j].c); } top=0; memset(tab,0,sizeof tab); for(int i=b[r^1][ts]; i; i=ee[r^1][i].f)if(ee[r^1][i].v!=tr)tab[ee[r^1][i].v]+=ee[r^1][i].c; for(int i=b[r^1][tr]; i; i=ee[r^1][i].f)if(ee[r^1][i].v!=ts)tab[ee[r^1][i].v]+=ee[r^1][i].c; rep(i,n)if(tab[i])add(r,ts,i,tab[i]); } printf("%d\n",ans); }}
阅读全文
0 0
- HDU 6081 度度熊的王国战略 堆优化Stoer-Wagner算法
- hdu6081 度度熊的王国战略(无向图全局最小割 stoer-wagner)
- hdu 6081 度度熊的王国战略
- hdu 6081 度度熊的王国战略
- poj2914 stoer wagner算法
- 无向图的最小割 hdu 3002 Stoer-wagner算法
- 最小割 Stoer-Wagner 算法
- 度度熊的王国战略
- 度度熊的王国战略
- 度度熊的王国战略
- 最小割集Stoer-Wagner算法【ZZ】
- 最小割集Stoer-Wagner算法
- 最小割集Stoer-Wagner算法
- 最小割集Stoer-Wagner算法
- Stoer-Wagner算法讲解(图+转载)
- 最小割集Stoer-Wagner算法
- 最小割Stoer-Wagner算法模板hdu3691
- Stoer-Wagner算法求全局最小割
- C\C++代码优化的27个建议
- StringBuffer与StringBuilder分析比较
- js高级教程 第六章-面对对象的程序设计(四)
- springmvc----源码分析之springmvc执行流程
- idea 上maven项目的创建以及部署到tomcat
- HDU 6081 度度熊的王国战略 堆优化Stoer-Wagner算法
- 算法竞赛入门经典 油田---经典的联通快问题
- iOS管理对象内存的数据结构以及操作算法--SideTables、RefcountMap、weak_table_t-二
- Java基础(三)数据类型与运算
- NYOJ 58 最少步数
- 多线程
- PAT A 1104. Sum of Number Segments (20)
- 网络题集
- HDMI介绍与流程