【BZOJ】【P1532】【POI2005】【Kos-Dicing】【二分+最大流】

来源:互联网 发布:淘宝飞猪客服电话 编辑:程序博客网 时间:2024/06/07 19:58

传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1532

最大值最小显然要二分

然后就是如何判定了

s->每场比赛 cap=1

每场比赛->对战双方 cap=1

每个选手->t cap=二分的答案

可行的话应该是满流的

然后你发现这是一个二分图

dinic跑二分图的优越性就体现了出来

总复杂度就变成了O(sqrt(n+m)*(n+m)*logm)

不知道sap能不能过

SAP过不了啦啦啦


Code:

#include<bits/stdc++.h>using namespace std;const int maxn=2e4+10;struct edge{int u,v,cap,flow;};vector<edge>edges;vector<int>G[maxn];void add(int u,int v,int cap){edges.push_back((edge){u,v,cap,0});G[u].push_back(edges.size()-1);edges.push_back((edge){v,u,0,0});G[v].push_back(edges.size()-1);}int n,m,s,t;int vis[maxn],d[maxn],cur[maxn];bool bfs(){memset(vis,0,sizeof vis);vis[s]=1;queue<int>q;q.push(s);d[s]=0;while(!q.empty()){int u=q.front();q.pop();for(int i=0;i<G[u].size();++i){edge e=edges[G[u][i]];if(!vis[e.v]&&e.cap>e.flow){vis[e.v]=1;d[e.v]=d[u]+1;q.push(e.v);}}}return vis[t];}int dfs(int u,int a){if(u==t||!a)return a;int flow=0,f;for(int &i=cur[u];i<G[u].size();i++){edge e=edges[G[u][i]];if(d[e.v]==d[u]+1&&(f=dfs(e.v,min(a,e.cap-e.flow)))>0){flow+=f;a-=f;edges[G[u][i]].flow+=f;edges[G[u][i]^1].flow-=f;if(!a)break;}}return flow;}int Dinic(){int flow=0,x;while(bfs()){memset(cur,0,sizeof cur);while(x=dfs(s,INT_MAX)){flow+=x;memset(cur,0,sizeof cur);}}return flow;}int main(){scanf("%d%d",&n,&m);s=0;t=n+m+1;for(int i=1;i<=m;i++){int u,v;scanf("%d%d",&u,&v);add(s,i,1);add(i,u+m,1);add(i,v+m,1);}int lf=edges.size();for(int i=1;i<=n;i++)add(i+m,t,0);int l=1,r=m;while(l<r){int mid=(l+r)>>1;for(int i=0;i<edges.size();i++)edges[i].flow=0;for(int i=lf;i<edges.size();i++)edges[i].cap=mid;if(Dinic()<m)l=mid+1;elser=mid;}cout<<l<<endl;return 0;}


0 0
原创粉丝点击