【unsolved最小割】POJ 1815

来源:互联网 发布:数组名可以做形参吗 编辑:程序博客网 时间:2024/04/28 02:23

ISAP

//#include <map>#include <set>#include <list>//#include <queue>#include <deque>#include <stack>#include <string>#include <cstdio>#include <math.h>#include <iomanip>#include <cstdlib>#include <limits.h>#include <string.h>#include <iostream>#include <fstream>#include <algorithm>using namespace std;#define LL long long#define pii pair<int ,int>#define bug cout<<"here!!"<<endl#define PI acos(-1.0)#define FRE freopen("input.txt","r",stdin)#define FF freopen("output.txt","w",stdout)#define eps 1e-8#define MIN INT_MIN#define MAX INT_MAX#define N 500const int MAXN=500;const int MAXM=500010;int n,m;//n为点数 m为边数int h[MAXN];int gap[MAXN];int p[MAXN],ecnt;int source,sink;int g[N][N];struct edge{    int v;    int next;//下一条边的编号    int val;//边权值}e[MAXM];inline void init(){memset(p,-1,sizeof(p));ecnt=0;}//有向inline void insert1(int from,int to,int val){    e[ecnt].v=to;    e[ecnt].val=val;    e[ecnt].next=p[from];    p[from]=ecnt++;    swap(from,to);    e[ecnt].v=to;    e[ecnt].val=0;    e[ecnt].next=p[from];    p[from]=ecnt++;}//无向inline void insert2(int from,int to,int val){    e[ecnt].v=to;    e[ecnt].val=val;    e[ecnt].next=p[from];    p[from]=ecnt++;    swap(from,to);    e[ecnt].v=to;    e[ecnt].val=val;    e[ecnt].next=p[from];    p[from]=ecnt++;}inline int dfs(int pos,int cost){    if (pos==sink){        return cost;    }    int j,minh=n-1,lv=cost,d;    for (j=p[pos];j!=-1;j=e[j].next){        int v=e[j].v,val=e[j].val;        if(val>0){            if (h[v]+1==h[pos]){                if (lv<e[j].val) d=lv;                else d=e[j].val;                d=dfs(v,d);                e[j].val-=d;                e[j^1].val+=d;                lv-=d;                if (h[source]>=n) return cost-lv;                if (lv==0) break;            }            if (h[v]<minh)   minh=h[v];        }    }    if (lv==cost){        --gap[h[pos]];        if (gap[h[pos]]==0) h[source]=n;        h[pos]=minh+1;        ++gap[h[pos]];    }    return cost-lv;}int sap(int st,int ed){    source=st;    sink=ed;    int ans=0;    memset(gap,0,sizeof(gap));    memset(h,0,sizeof(h));    gap[st]=n;    while (h[st]<n){        ans+=dfs(st,INT_MAX);    }    return ans;}bool vis[N];int an[N];int main(){FRE;    int s,t;    while(scanf("%d%d%d",&n,&s,&t) != -1){        int i,j,k;        memset(g,0,sizeof(g));        init();        for(i=1;i<=n;i++){            if(i!=s && i!=t){                insert1(i,i+n,1);            } else insert1(i,i+n,MAX);        }        for(i=1;i<=n;i++){            for(j=1;j<=n;j++){                scanf("%d",&g[i][j]);                if(g[i][j] && i!=t && j!=s && i!=j){                    //cout<<i<<" "<<j<<endl;                    insert1(i+n,j,MAX);                }            }        }        if(g[s][t]){            puts("NO ANSWER!");            continue;        } else {            memset(vis,0,sizeof(vis));            int cnt=0;            int nn = n;            n = 2*n;            int pre = sap(s,t);//cout<<pre<<endl;            for(i=1;i<=nn;i++){                if(i==s || i==t)continue;//cout<<i<<endl;                vis[i] = 1;                init();                for(j=1;j<=nn;j++){                    if(vis[j])continue;                    else if(j!=s && j!= t)insert1(j,j+nn,1);                    else insert1(j,j+nn,MAX);                }                for(j=1;j<=nn;j++){                    for(k=1;k<=nn;k++){                        if(g[j][k] && j!=t && k!=s && !vis[j] && !vis[k]){                            insert1(j+nn,k,MAX);                        }                    }                }                int gao = sap(s,t);                if(gao < pre){                    pre = gao;                    an[cnt++] = i;                } else {                    vis[i] = 0;                }            }            printf("%d\n",cnt);            printf("%d",an[0]);            for(i=1;i<cnt;i++)printf(" %d",an[i]);            puts("");        }    }    return 0;}


原创粉丝点击