bzoj 1937: [Shoi2004]Mst 最小生成树
2016-06-21 19:18
260 查看
将原问题对偶成为费用流模型;
写的原始对偶的费用流,然后发现每次增广容量最多为1…mdzz
写的原始对偶的费用流,然后发现每次增广容量最多为1…mdzz
#include<bits/stdc++.h> #define rep(i,k,n) for(int i=k;i<=(n);i++) #define rep2(i,k,n) for(int i=k;i>=(n);i--) #define mp make_pair using namespace std; const int N=1005; const int M=100005; const int inf=0x3f3f3f3f; struct E{ int fr,to,next,cap,c;E(int fr=0,int to=0,int next=0,int cap=0,int c=0):fr(fr),to(to),next(next),cap(cap),c(c){} }edge[M]; int head ,tot=1; void Add(int x,int y,int cap,int cost){ edge[++tot]=E(x,y,head[x],cap,cost);head[x]=tot; edge[++tot]=E(y,x,head[y],0,-cost);head[y]=tot; } int n,m,op ,V ,cnt=0,S,T; map<pair<int,int>,int> st; map<int,pair<int,int> > nst; namespace tu{ struct E2{ int fr,to,next,num;E2(int fr=0,int to=0,int next=0,int num=0):fr(fr),to(to),next(next),num(num){} }edge[M]; int head ,tot=0; void add(int x,int y,int num){ edge[++tot]=E2(x,y,head[x],num);head[x]=tot; edge[++tot]=E2(y,x,head[y],num);head[y]=tot; } int p ,ok; void dfs(int u,int v,int fa){ if(u==v)ok=1; if(ok)return; for(int i=head[u];i;i=edge[i].next)if(op[edge[i].num]){ int to=edge[i].to; if(to!=fa){ p[to]=i; dfs(to,v,u); } } } void init(){int u,v; rep(i,1,cnt)if(!op[i]){ memset(p,0,sizeof(p));ok=0; u=nst[i].first,v=nst[i].second; dfs(u,v,0); int now=p[v]; while(now){ Add(edge[now].num,i,1,V[edge[now].num]-V[i]); now=p[edge[now].fr]; } } } } int inq ,cur ,dis ; queue<int> Q; bool spfa(){ memset(inq,0,sizeof(inq)); memset(dis,-0x7f,sizeof(dis)); memcpy(cur,head,sizeof(head)); dis[T]=0;inq[T]=1; Q.push(T); while(!Q.empty()){ int u=Q.front(); Q.pop();inq[u]=0; for(int i=head[u];i;i=edge[i].next)if(edge[i^1].cap){ int v=edge[i].to,w=edge[i].c; if(dis[v]<dis[u]-w){ dis[v]=dis[u]-w; if(!inq[v]){inq[v]=1;Q.push(v);} } } } return dis[S]>-inf; } int vis ; int dfs(int u,int a){ vis[u]=1; if(!a || u==T)return a; int f,flow=0; for(int& i=cur[u];i;i=edge[i].next)if(edge[i].cap){ int v=edge[i].to,cc=edge[i].cap; if(dis[v]+edge[i].c==dis[u] && !vis[v]){ f=dfs(v,min(a,cc)); if(f){ edge[i].cap-=f; edge[i^1].cap+=f; flow+=f; a-=f; if(!a)return flow; } } } return flow; } int main(){ // freopen("in.in","r",stdin); // freopen("out.out","w",stdout); scanf("%d%d",&n,&m);int x,y,w; rep(i,1,m){ scanf("%d%d",&x,&y);if(x>y)swap(x,y); st[mp(x,y)]=++cnt; nst[cnt]=mp(x,y); scanf("%d",&w); V[cnt]=w; tu::add(x,y,cnt); }rep(i,1,n-1){ scanf("%d%d",&x,&y);if(x>y)swap(x,y); op[st[mp(x,y)]]=1; }tu::init(); S=++cnt,T=++cnt; rep(i,1,cnt-2) if(op[i])Add(S,i,1,0); else Add(i,T,1,0); int ans=0; while(spfa()){ if(dis[S]<=0)break; memset(vis,0,sizeof(vis)); ans+=dis[S]*dfs(S,inf); }printf("%d\n",ans); }
相关文章推荐
- Large scale optimization
- 线性规划
- Mathematica在线性规划中的应用实例
- Linear Programming Learning Notes (3) Degeneracy
- Linear Programming Learning Notes (2) The Simplex Method
- Linear Programming Learning Notes (1) Introduction
- 小点滴——Lingo的非线性规划、最优化求解
- 线性规划与网络流24题
- matlab_线性规划
- 【Codeforces Round 335 (Div 2)E】【计算几何-凸包 线性规划 三分凸包上最优点】Freelancer's Dreams 二维属性 充最少的钱变得满足要求 [计算几何-凸包模
- 【代码系列】POJ 1273( 单纯形解最大流 )
- 【BZOJ3265】志愿者招募加强版【单纯形法】
- 【BZOJ1061】[Noi2008]志愿者招募【单纯形法】
- [Machine learning 实验4]linear programming
- Linner Programming Package GLPK and LP
- 修正单纯形法·优化算法实现·Java
- 线性规划工具 GLPK 的安装及基本使用
- 线性规划问题解决开源工具(GNU Linear Programming Kit)
- 过剩通勤应用——线性规划问题解决开源工具(下篇)
- vijos1431[noip2007]守望者的逃离(背包动规)