BZOJ4663: Hack
来源:互联网 发布:打电话的软件 编辑:程序博客网 时间:2024/06/06 21:03
最小割
要求0-n-1的每一条路径上有且仅有一条被控制的边
正常情况下跑最小割,每条路上是只会割一条的,但是有些非正常情况
要不你们看这篇?这篇有图…
然后…我不知道为什么要这样建图,是怎么想的(有人会了告诉我一声?)…..但是这样建图是对的..因为它能避免所有非法情况…
只处理起点能到的点,最后答案超过inf即无解(终点在环内)
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define inf 1e12using namespace std;const int maxn = 1100;const int maxm = 25100;int st,ed,n,m;int e[maxm][3];struct edge{ int y,nex; ll c; edge(){} edge(const int _y,const ll _c,const int _nex){y=_y;c=_c;nex=_nex;}}a[maxm]; int len,fir[maxn],fi[maxn];inline void ins(const int x,const int y,const ll c){ a[++len]=edge(y,c,fir[x]); fir[x]=len;}inline void ins2(const int x,const int y,const ll c){ a[++len]=edge(y,c,fir[x]); fir[x]=len; a[++len]=edge(x,inf,fir[y]); fir[y]=len;}bool v[maxn];queue<int>q;void mark(){ v[st]=true; q.push(st); while(!q.empty()) { const int x=q.front(); q.pop(); for(int k=fir[x];k;k=a[k].nex) { const int y=a[k].y; if(!v[y]) v[y]=true,q.push(y); } }}int h[maxn];bool bfs(){ for(int i=1;i<=ed;i++) h[i]=0; h[st]=1; q.push(st); while(!q.empty()) { const int x=q.front(); q.pop(); for(int k=fir[x];k;k=a[k].nex) { const int y=a[k].y; if(!h[y]&&a[k].c) h[y]=h[x]+1,q.push(y); } } return h[ed]>0;}ll dfs(const int x,const ll flow){ if(x==ed) return flow; ll delta=0; for(int &k=fi[x];k;k=a[k].nex) { const int y=a[k].y; if(h[y]==h[x]+1&&a[k].c) { ll mink=dfs(y,min(flow-delta,a[k].c)); delta+=mink; a[k].c-=mink; a[k^1].c+=mink; } if(delta==flow) return delta; } return delta;}ll Flow(){ ll r=0; while(bfs()) { for(int i=1;i<=ed;i++) fi[i]=fir[i]; r+=dfs(st,LLONG_MAX); } return r;}int main(){ scanf("%d%d",&n,&m); st=1; ed=n; len=0; for(int i=1;i<=m;i++) { int x,y,c; scanf("%d%d%d",&x,&y,&c); x++; y++; e[i][0]=x; e[i][1]=y; e[i][2]=c; ins(x,y,c); } mark(); len=1; for(int i=1;i<=ed;i++) fir[i]=0; for(int i=1;i<=m;i++) if(v[e[i][0]]&&v[e[i][1]]) ins2(e[i][0],e[i][1],e[i][2]); ll r=Flow(); if(r>inf) printf("-1\n"); else printf("%lld\n",r); return 0;}
0 0
- bzoj4663 Hack
- BZOJ4663: Hack
- HACK
- HACK
- hack
- Hack
- hack
- hack
- hack
- hack
- HACK
- hack
- hack
- 【Hack】ie 条件Hack
- Google Hack
- XOOPS HACK
- Cocoa Hack
- Hack Game
- 如何批量修改文件名
- R语言-决策树算法(C4.5和CART)的实现
- JavaScript Tips
- 关于svn的安装部署
- web上种图片应用的优缺点
- BZOJ4663: Hack
- Angular跳坑之旅——入门
- 矩阵连乘
- 注册页面需要的js代码
- Win平台安装Docker
- 对百度地图使用的总结
- 【转载】说说JSON和JSONP,也许你会豁然开朗,含jQuery用例
- 使用JavaScript实现回到顶部效果
- Hibernate框架环境搭建简述