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

来源:互联网 发布:mssql server 2008 r2 编辑:程序博客网 时间:2024/05/21 21:49

用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]);}       


0 0
原创粉丝点击