您的位置:首页 > 理论基础 > 计算机网络

Andrew Stankevich Contest 10 I Trade 有下届网络流

2016-09-13 11:24 323 查看
用Dinic跑一遍,关键是建图

#include<bits/stdc++.h>
#define MEM(a,x) memset(a,x,sizeof(a));
#define MEMINF(a) memset(a,0x3f,sizeof(a));
using namespace std;
typedef long long LL;
const int MAXN=1e6+10;
const int INF=0x3f3f3f3f;
const int MOD=1000000007;
struct Edge{
int to,nex,cap,id;
}edge[MAXN];

int top;
int head[MAXN],gap[MAXN],point[MAXN];
void Addedges(int u,int v,int cap,int id) {
edge[top].id=id;
edge[top].cap=cap;
edge[top].to=v;
edge[top].nex=head[u];
head[u]=top++;
}

void Addedge(int u,int v,int cap,int id) {
Addedges(u,v,cap,id);
Addedges(v,u,0,id);
}

int  bfs(int s,int t) {
MEM(gap,-1);
queue<int>q;
gap[s]=0;
q.push(s);
while (!q.empty()) {
int u=q.front();
q.pop();
for (int i=head[u]; ~i; i=edge[i].nex) {
int v=edge[i].to,cap=edge[i].cap;
if (cap>0&&gap[v]<0) {
gap[v]=gap[u]+1;
q.push(v);
}
}
}
return gap[t];
}

int dfs(int s,int t,int flow) {
int f;
if (s==t) return flow;
for (int i=head[s]; ~i; i=edge[i].nex) {
if (edge[i].cap>0&&gap[s]<gap[edge[i].to])
if ((f=dfs(edge[i].to,t,min(flow,edge[i].cap)))>0) {
edge[i].cap-=f;
edge[i^1].cap+=f;
return f;
}
}
return 0;
}
int Dinic (int s,int t,int cntV) {
int flow=0;
int f;
while(bfs(s,t)>=0) {
while((f=dfs(s,t,INF))>0)
flow+=f;
}
return flow;
}
int main() {
freopen("trade.in","r",stdin);
freopen("trade.out","w",stdout);
int m,n,p;
cin>>m>>n>>p;
MEM(head,-1);
top=0;
int s=m+n,t=m+n+1;
int cntS=m+n+2,cntT=m+n+3;
int cntV=m+n+4;
for (int i=1; i<=p; ++i) {
int u,v;
scanf("%d %d",&u,&v);
Addedge(u-1,m+v-1,1,i);
}
for (int i=0; i<m; ++i) {
Addedge(s,i,INF,0);
Addedge(cntS,i,2,0);
}
for(int i=0; i<n; ++i) {
Addedge(i+m,t,INF,0);
Addedge(i+m,cntT,2,0);
}
Addedge(s,cntT,2*m,0);
Addedge(cntS,t,2*n,0);
int tflow=n*2+m*2;
int tmp=Dinic(cntS,cntT,cntV);
Addedge(t,s,INF,0);
tmp+=Dinic(cntS,cntT,cntV);
if (tmp!=tflow) {
puts("-1");
return 0;
}
vector<int>ans;
for (int i=0; i<m; ++i) {
for (int u=head[i]; ~u; u=edge[u].nex) {
if (edge[u].cap==0&&(edge[u].to>=m&&edge[u].to<n+m))
ans.push_back(edge[u].id);
}
}
printf("%d\n",(int) ans.size());
sort(ans.begin(),ans.end());
printf("%d ",ans[0]);
for (int i=1; i<ans.size(); ++i)
printf("%d%c",ans[i]," \n"[i==ans.size()-1]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM C++ 网络流