2017Astar资格赛1002 度度熊的王国战略

来源:互联网 发布:mac vim 修改只读文件 编辑:程序博客网 时间:2024/06/04 10:29

啊啊全局最小割?

看了一天没看懂

考虑一个最小割,把原图分成两半(废话

左边取一个点为S,右边去一个点为T,跑出来的最小割一定是答案(废话

于是取1为S,随机T,1000组,保证不重复,随机数据随便过

但是有卡点,3000个点被分成了2999+1或2998+2

这两种情况都是可以预处理的

当2997+3时有三个点随机到一个就行,1000次,A掉的概率有,大概每个点70%

想想卡点不多(2999+1,2998+2为主),随机至上(笑),反正过了


#include <ctime>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define rep(j,k,l) for (int j=k;j<=l;++j)#define red(j,k,l) for (int j=k;j>=l;--j)#define N 3005#define M 100005*2#define inf 1000000007#define min(a,b) (((a)<(b))?(a):(b))using namespace std;int n,m,a[M],b[M],c[M],d[M],e[M],pos;struct Dinic{        int st[N],to[M],ne[M],mx[M],fl[M],deep[N],que[N],cur[N],S,T,cnt;    void add(int k,int l,int poi){                to[++cnt]=l;        mx[cnt]=poi;        ne[cnt]=st[k];        st[k]=cnt;        fl[cnt]=0;        //if (poi>0) cout<<k<<' '<<l<<' '<<poi<<endl;            }        void set(){        S=1,T=d[++pos];        cnt=1;rep(i,1,n) st[i]=0;        rep(i,1,m) add(a[i],b[i],c[i]),add(b[i],a[i],c[i]);            }        bool bfs(){        int head=0,tail=1;        que[1]=S;memset(deep,0,sizeof(deep));        deep[S]=1;        while (head!=tail){            int x=que[++head];            for (int i=st[x];i;i=ne[i])                if (deep[to[i]]==0&&fl[i]!=mx[i]){                                        deep[to[i]]=deep[x]+1;                    que[++tail]=to[i];                    if (to[i]==T) return 1;                                    }                    }        return deep[T]>0;            }        int dfs(int k,int re){                if (k==T||re==0) return re;        int flow=0,f;        for (int i=cur[k];i;cur[k]=i=ne[i])            if (deep[to[i]]==deep[k]+1&&(f=dfs(to[i],min(re,mx[i]-fl[i])))>0){                //printf("--!--%d %d\n",k,f);                fl[i]+=f;fl[i^1]-=f;                flow+=f;re-=f;                if (!re) return flow;                            }        if (re) deep[k]=-1;        return flow;            }        int maxflow(){                int flow=0;        while (bfs()){            //puts("ok");            rep(i,1,n) cur[i]=st[i];  //зЂвт            flow+=dfs(S,inf);                    }//printf("----%d\n",flow);        return flow;            }    } F;int main(){srand(time(0));while (scanf("%d%d",&n,&m)!=EOF){for (int i=1;i<n;i++) d[i]=i+1;random_shuffle(d+1,d+n);pos=0;memset(e,0,sizeof(e));rep(i,1,m)scanf("%d%d%d",a+i,b+i,c+i),e[a[i]]+=c[i],e[b[i]]+=c[i];int ans=inf,pi;rep(i,1,n) ans=min(ans,e[i]);rep(i,1,m) ans=min(ans,e[a[i]]+e[b[i]]-2*c[i]);rep(i,1,min(500,n-1)) F.set(),pi=F.maxflow(),ans=min(ans,pi);printf("%d\n",ans);}    }

阅读全文
0 0