POJ2699 The Maximum Number of Strong Kings(最大流)
2015-12-31 10:48
417 查看
枚举所有Strong King的状态(最多1024种左右),然后判断是否合法。
判定合法用网络流,源点-比赛-人-汇点,这样连边。
源点向每场比赛连容量为1的边;
如果一场比赛,A和B,A是Strong King且A的胜场小于B那么这场比赛向A连容量1的边,否则这场比赛向A和B都连容量1的边;
每个人向汇点连容量为胜场的边。
最后如果最大流等于所有人胜场和那就是合法的一个解。
判定合法用网络流,源点-比赛-人-汇点,这样连边。
源点向每场比赛连容量为1的边;
如果一场比赛,A和B,A是Strong King且A的胜场小于B那么这场比赛向A连容量1的边,否则这场比赛向A和B都连容量1的边;
每个人向汇点连容量为胜场的边。
最后如果最大流等于所有人胜场和那就是合法的一个解。
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define MAXN 222 #define MAXM 222*222*2 #define INF (1<<30) struct Edge{ int v,cap,flow,next; }edge[MAXM]; int vs,vt,NE,NV; int head[MAXN]; void addEdge(int u,int v,int cap){ edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=0; edge[NE].next=head[u]; head[u]=NE++; edge[NE].v=u; edge[NE].cap=0; edge[NE].flow=0; edge[NE].next=head[v]; head[v]=NE++; } int level[MAXN]; int gap[MAXN]; void bfs(){ memset(level,-1,sizeof(level)); memset(gap,0,sizeof(gap)); level[vt]=0; gap[level[vt]]++; queue<int> que; que.push(vt); while(!que.empty()){ int u=que.front(); que.pop(); for(int i=head[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(level[v]!=-1) continue; level[v]=level[u]+1; gap[level[v]]++; que.push(v); } } } int pre[MAXN]; int cur[MAXN]; int ISAP(){ bfs(); memset(pre,-1,sizeof(pre)); memcpy(cur,head,sizeof(head)); int u=pre[vs]=vs,flow=0,aug=INF; gap[0]=NV; while(level[vs]<NV){ bool flag=false; for(int &i=cur[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(edge[i].cap!=edge[i].flow && level[u]==level[v]+1){ flag=true; pre[v]=u; u=v; //aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap)); aug=min(aug,edge[i].cap-edge[i].flow); if(v==vt){ flow+=aug; for(u=pre[v]; v!=vs; v=u,u=pre[u]){ edge[cur[u]].flow+=aug; edge[cur[u]^1].flow-=aug; } //aug=-1; aug=INF; } break; } } if(flag) continue; int minlevel=NV; for(int i=head[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(edge[i].cap!=edge[i].flow && level[v]<minlevel){ minlevel=level[v]; cur[u]=i; } } if(--gap[level[u]]==0) break; level[u]=minlevel+1; gap[level[u]]++; u=pre[u]; } return flow; } inline int in(int &ret){ char c; ret=0; while(c=getchar(),c<'0'||c>'9') if(c=='\n'||c==EOF) return -1; while(c>='0'&&c<='9') ret=ret*10+c-'0',c=getchar(); if(c=='\n'||c==EOF) return 0; return 1; } int win[11],n; bool isStatue(int s){ for(int i=0;i<n;++i){ if((s>>i)&1) continue; if(win[s]==win[n-1]) return 0; } return 1; } int getCnt(int s){ int cnt=0; for(int i=0;i<n;++i){ if((s>>i)&1) ++cnt; } return cnt; } int main(){ int t; scanf("%d ",&t); while(t--){ n=0; int tmp; while(tmp=in(win ),tmp==1) ++n; if(tmp==0) ++n; int tot=0; for(int i=0; i<n; ++i) tot+=win[i]; int res=0; for(int s=1; s<(1<<n); ++s){ if(!isStatue(s)) continue; memset(head,-1,sizeof(head)); vs=200; vt=201; NV=202; NE=0; for(int i=0; i<n; ++i){ addEdge(i+n*n,vt,win[i]); } for(int i=0; i<n; ++i){ for(int j=i+1; j<n; ++j){ addEdge(vs,i*n+j,1); if(((s>>i)&1) && win[i]<win[j]) addEdge(i*n+j,i+n*n,1); else if(((s>>j)&1) && win[j]<win[i]) addEdge(i*n+j,j+n*n,1); else{ addEdge(i*n+j,i+n*n,1); addEdge(i*n+j,j+n*n,1); } } } if(ISAP()==tot) res=max(res,getCnt(s)); } printf("%d\n",res); } return 0; }
相关文章推荐
- Web相关开发——JavaScript
- 对金钱的嗅觉
- Android中Activity.this,getApplicationContext(),getBaseContext()和this详解
- 扩展SpringMVC以支持绑定JSON格式的请求参数
- ArcGIS教程:表面等值线的工作原理
- GitHub教程
- jQuery动画效果相关方法实例分析
- 微信企业红包发放注意事项记录
- Android中隐士自动跳转到系统设置界面
- python实现爬虫统计学校BBS男女比例(二)多线程爬虫
- oracle 11.2.0.4.0导入导出笔记
- 各种编码格式的比较
- Invert a binary tree
- android中将一个项目作为library导入另一个项目中
- Android电话录音
- 用securecrt同时操作多台服务器
- 坐标系、变换及缓冲区及操作矩阵的通用变换函数(openGL)
- Java高级特性之枚举
- 聚类算法-DBSCAN-C++实现
- Sphinx按某个字段搜索过滤