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