ZOJ 3933(网络流)

来源:互联网 发布:英语学习软件下载 编辑:程序博客网 时间:2024/06/06 14:23

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5693


题目大意:给出两个队伍中的人,使其不同队的组合尽量多,还要最大化女生,其中还有人不愿意跟某个人组队。

我用费用流来做,女生费用为0,男生为1。不同队伍的点之间有边,同一个队的没有边相连,且不愿意组队的两个点也不会有边。

折磨我了半天,找不到超时原因,就按网上题解,把边改成用vector来存就过了。

AC代码:

/*--------------------------------------------------------                       Author:log                            Created Time:2016年04月23日 星期六 12时27分38秒--------------------------------------------------------*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <map>using namespace std;const int maxn=505;const int inf=0x3f3f3f3f;struct Edge{int from,to;int f,c,v;Edge(int from,int to,int f,int c,int v):from(from),to(to),c(c),f(f),v(v){}};vector<Edge>edge;vector<int>G[maxn];int cot;int st,ed;int n;inline void addedge(int from,int to,int c,int v){edge.push_back(Edge(from,to,0,c,v));edge.push_back(Edge(to,from,0,0,-v));int len=edge.size()-1;G[to].push_back(len);G[from].push_back(len-1);}int fa[maxn];bool vis[maxn];int dist[maxn];bool hate[maxn];int a[maxn];int ans1,ans2;queue<int>q;bool SPFA(){int u;memset(vis,0,sizeof(vis));memset(fa,-1,sizeof(fa));for(int i=0;i<=ed;i++)dist[i]=inf;dist[st]=0;vis[st]=true;a[st]=inf;q.push(st);while(!q.empty()){u=q.front();q.pop();vis[u]=false;for(int i=0;i<G[u].size();i++){Edge& e=edge[G[u][i]];//printf("e.to:%d\n",e.to);//printf("e.c:%d e.f:%d",e.c,e.f);if(e.c>e.f&&dist[e.to]>dist[u]+e.v){fa[e.to]=G[u][i];dist[e.to]=dist[u]+e.v;a[e.to]=min(a[u],e.c-e.f);if(!vis[e.to]){q.push(e.to);vis[e.to]=true;}}}}if(dist[ed]==inf)return false;ans1+=a[ed];ans2+=dist[ed]*a[ed];u=ed;while(u!=st){edge[fa[u]].f+=a[ed];edge[fa[u]^1].f-=a[ed];u=edge[fa[u]].from;}return true;}void solve(){ans1=ans2=0;while(SPFA());printf("%d %d\n",ans1,2*ans1-ans2);for(int i=0;i<edge.size();i+=2){if(edge[i].from==0||edge[i].to==ed||edge[i].f==0)continue;printf("%d %d\n",edge[i].from,edge[i].to);}}char ch1[maxn],ch2[maxn];int main(){int t;int v;scanf("%d",&t);while(t--){for(int i=0;i<=ed;i++)G[i].clear();edge.clear();scanf("%d",&n);scanf("%s",ch1+1);scanf("%s",ch2+1);int m;st=0,ed=n+1;for(int i=1;i<=n;i++){if(ch1[i]=='0'){addedge(st,i,1,0);}else {addedge(i,ed,1,0);}scanf("%d",&m);memset(hate,0,sizeof(hate));for(int j=1;j<=m;j++){scanf("%d",&v);hate[v]=true;}if(ch1[i]=='1')continue;v=(ch2[i]=='1');for(int j=1;j<=n;j++){if(hate[j]||ch1[i]==ch1[j])continue;addedge(i,j,1,ch2[i]-'0'+ch2[j]-'0');}}solve();/*for(int i=0;i<edge.size();i++){printf("cot:%d from:%d to:%d ",i,edge[i].from,edge[i].to);printf("c:%d f:%d v:%d\n",edge[i].c,edge[i].f,edge[i].v);}*/}    return 0;}

超时代码:

/*--------------------------------------------------------                       Author:log                            Created Time:2016年04月23日 星期六 12时27分38秒--------------------------------------------------------*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <map>using namespace std;const int maxn=505;const int inf=0x3f3f3f3f;struct Edge{int from,to,ne;int f,c,v;}e[maxn*maxn];int head[maxn];int cot;int st,ed;int n;inline void addedge(int from,int to,int c,int v){e[cot]=(Edge){from,to,head[from],0,c,v};head[from]=cot++;e[cot]=(Edge){to,from,head[to],0,0,-v};head[to]=cot++;}int fa[maxn];bool vis[maxn];int dist[maxn];bool hate[maxn][maxn];int a[maxn];int ans1,ans2;queue<int>q;bool SPFA(){int u;memset(vis,0,sizeof(vis));memset(fa,-1,sizeof(fa));for(int i=0;i<=n;i++)dist[i]=inf;dist[st]=0;vis[st]=true;a[st]=inf;q.push(st);while(!q.empty()){u=q.front();q.pop();vis[u]=false;for(int i=head[u];i!=-1;i=e[i].ne){if(e[i].c>e[i].f&&dist[e[i].to]>dist[u]+e[i].v){fa[e[i].to]=i;dist[e[i].to]=dist[u]+e[i].v;a[e[i].to]=min(a[u],e[i].c-e[i].f);if(!vis[e[i].to]){q.push(e[i].to);vis[e[i].to]=true;}}}}if(dist[ed]==inf){return false;}ans1+=a[ed];ans2+=dist[ed]*a[ed];u=ed;while(u!=st){e[fa[u]].f+=a[ed];e[fa[u]^1].f-=a[ed];u=e[fa[u]].from;}return true;}void solve(){ans1=ans2=0;while(SPFA());printf("%d %d\n",ans1,2*ans1-ans2);for(int i=0;i<cot;i+=2){if(e[i].from==0||e[i].to==ed||e[i].f==0)continue;printf("%d %d\n",e[i].from,e[i].to);}}char ch1[maxn],ch2[maxn];int main(){int t;int v;scanf("%d",&t);while(t--){for(int i=0;i<maxn;i++)head[i]=-1;cot=0;memset(hate,0,sizeof(hate));scanf("%d",&n);scanf("%s",ch1+1);scanf("%s",ch2+1);int m;for(int i=1;i<=n;i++){scanf("%d",&m);for(int j=0;j<m;j++){scanf("%d",&v);hate[i][v]=true;hate[v][i]=true;}}st=0,ed=n+1;for(int i=n;i>=1;i--){if(ch1[i]=='0'){addedge(st,i,1,0);}else {addedge(i,ed,1,0);}if(ch1[i]=='1')continue;v=(ch2[i]=='1');for(int j=1;j<=n;j++){if(hate[i][j]||ch1[i]==ch1[j])continue;addedge(i,j,1,ch2[i]-'0'+ch2[j]-'0');}}n++;solve();/*for(int i=0;i<cot;i++){printf("cot:%d from:%d to:%d ",i,e[i].from,e[i].to);printf("c:%d f:%d v:%d\n",e[i].c,e[i].f,e[i].v);}*/}    return 0;}


0 0
原创粉丝点击