网络流+拆点+sap+uva10330
2014-01-15 21:23
120 查看
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int maxn=210; const int INF=0x3f3f3f3f; struct node { int v,next,f; } edge[maxn*maxn]; int pre[maxn],cur[maxn],gap[maxn],head[maxn],dis[maxn]; int N,M,num,B,D,nn; void init() { num=0; memset(head,-1,sizeof(head)); } void add_edge(int a,int b,int x) { edge[num].v=b; edge[num].next=head[a]; edge[num].f=x; head[a]=num++; edge[num].v=a; edge[num].next=head[b]; edge[num].f=0; head[b]=num++; } int SAP(int s,int t) { for(int i=0; i<=nn; i++) { cur[i]=head[i]; gap[i]=dis[i]=0; } int u; int flow=0,aug=INF; gap[s]=nn; u=pre[s]=s; bool flag; while(dis[s]<nn) { flag=0; for(int &j=cur[u]; j!=-1; j=edge[j].next) { int v=edge[j].v; if(edge[j].f>0&&dis[u]==dis[v]+1) { flag=1; if(edge[j].f<aug) aug=edge[j].f; pre[v]=u; u=v; if(u==t) { flow+=aug; while(u!=s) { u=pre[u]; edge[cur[u]].f-=aug; edge[cur[u]^1].f+=aug; } aug=INF; } break; } } if(flag) continue; int mindis=nn; for(int j=head[u];j!=-1;j=edge[j].next) { int v=edge[j].v; if(dis[v]<mindis&&edge[j].f>0) { mindis=dis[v]; cur[u]=j; } } if((--gap[dis[u]])==0) break; gap[dis[u]=mindis+1]++; u=pre[u]; } return flow; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int a,b,x; while(cin>>N) { init(); for(int i=1; i<=N; i++) { cin>>x; add_edge(i,i+N,x); } cin>>M; for(int i=0; i<M; i++) { cin>>a>>b>>x; add_edge(a+N,b,x); } cin>>B>>D; for(int i=1; i<=B; i++) { cin>>a; add_edge(0,a,INF); } for(int i=1; i<=D; i++) { cin>>a; add_edge(a+N,2*N+1,INF); } nn=2*(N+1); cout<<SAP(0,2*N+1)<<endl; } return 0; }
下面是EK
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<set> #include<queue> #include<string> #include<cmath> #include<fstream> #include<iomanip> using namespace std; #define MAX_INT 0x7fffffff #define MAX_LL 0x7fffffffffffffff #define ULL unsigned long long #define LL long long #define MAX(x,y) ((x) > (y) ? (x) : (y)) #define MIN(x,y) ((x) < (y) ? (x) : (y)) #define MAXN 222 #define MAXM 22222 #define INF (MAX_INT>>1) int cap[MAXN][MAXN]; int n,m,b,d; int flow[MAXN][MAXN]; int p[MAXN]; queue<int> q; int Edmonds_Karp(int s, int t){ int a[MAXN],f=0; memset(flow,0,sizeof(flow)); //从0开始 while(!q.empty()) q.pop(); while(1){ memset(a,0,sizeof(a)); a[s]=INF; q.push(s); //000 while(!q.empty()){ //BFS int u=q.front(); q.pop(); for(int v=0; v<=n; v++) if(!a[v] && cap[u][v]>flow[u][v]){ a[v]=MIN(a[u],cap[u][v]-flow[u][v]); //更新,还不特别清楚。。。 p[v]=u; q.push(v); } } if(!a[t]) break; for(int v=t; v!=s; v=p[v]){ flow[p[v]][v]+=a[t]; //更新当前流量 flow[v][p[v]]-=a[t]; } f+=a[t]; } return f; } int main(){ //freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin); while(scanf(" %d",&n)==1){ int i,j,t2,t1,w_; memset(cap,0,sizeof(cap)); //拆点,把点i拆成i、n+i for(i=1; i<=n; i++) scanf(" %d",&cap[i][n+i]); scanf(" %d",&m); for(i=1; i<=m; i++){ scanf(" %d %d %d",&t1,&t2,&w_); cap[n+t1][t2]=w_; //注意弧的始终点 } scanf(" %d %d",&b,&d); for(i=1; i<=b; i++){ scanf(" %d",&t1); cap[0][t1]=INF; } for(i=1; i<=d; i++){ scanf(" %d",&t1); cap[t1+n][2*n+1]=INF; } n=n*2+1; cout<<Edmonds_Karp(0,n)<<endl; } return 0; }
相关文章推荐
- 【网络流】飞行员配对方案问题
- 网络流图形简化
- 【网络流】 Codeforces Round #290 (Div. 1) C. Fox And Dinner
- A simple Gaussian elimination problem.(hdu4975)网络流+最大流
- [洛谷 P1402] 酒店之王|网络流
- 网络流题集
- kebab (hdu 2883 网络流判满流 关键是缩点)
- wind的网络流神模板--【秒过。。】【网络流】
- POJ 2699 - The Maximum Number of Strong Kings(网络流‘最大流)
- zoj 2587 - Unique Attack(网络流’最小割)
- 网络流(三)----最大流SAP算法
- 网络流基础学习(Edmonds_Karp算法 )
- 【网络流】【最小点权覆盖】【NEERC 2003】【POJ2125】【cogs 1575】有向图破坏
- 有所述网络流的上限和下限
- poj 1149 PIGS (网络流最大流Dinic)
- [网络流24题] 01 搭配飞行员(最大流)
- POJ2391 Ombrophobic Bovines 网络流拆点+二分+floyed
- POJ1459网络流模板题
- [网络流24题] 05 圆桌聚餐(最大流判满流)
- Drainage Ditches - poj 1273(网络流模板)