2012 TCO Algorithm Round 3A - Division I, Level Two FoxAndCake

来源:互联网 发布:弱肉强食知乎 编辑:程序博客网 时间:2024/05/17 03:34

竟然是网络流问题!

因为每个联通块要含有两种东西,且每个格子都只能出现在一个联通块上,所以我们可以吧一个联通块看成从一种东西到另一种东西的路径。为了实现第二个条件,我们在每个点上限制流量就可以了。那么现在的问题就是图太大了。但是只有7个点,我们可以把有用的X,Y坐标离散化出来。官方题解证明了对与每一个X,只要提取出[X-3,X+3]这7个数字就可以了。这样我们建图跑最大流就可以了。

#include <bits/stdc++.h>#define maxn 6000#define maxm 2000009using namespace std;const int INF=1e9;struct Edge{    int v,next,cap;}edge[maxm];int head[maxn],h[maxn],gap[maxn],tot,n,src,des,N;inline void addedge(int u,int v,int cap){ //  printf(">>%d %d\n",u,v);    edge[tot].v=v;    edge[tot].cap=cap;    edge[tot].next=head[u];    head[u]=tot++;    edge[tot].v=u;    edge[tot].cap=0;    edge[tot].next=head[v];    head[v]=tot++;}inline int dfs(int u,int cap){    if(u==des)return cap;    int minh=n-1;    int lv=cap,d;    for(int e=head[u];e!=-1;e=edge[e].next)    {        int v=edge[e].v;        int w=edge[e].cap;        if(w>0)        {            if(h[v]+1==h[u])            {                d=min(lv,edge[e].cap);                d=dfs(v,d);                edge[e].cap-=d;                edge[e^1].cap+=d;                lv-=d;                if(h[src]>=n)return cap-lv;                if(lv==0)                    break;            }            minh=min(minh,h[v]);        }    }    if(lv==cap)    {        --gap[h[u]];        if(gap[h[u]]==0)h[src]=n;        h[u]=minh+1;        ++gap[h[u]];    }    return cap-lv;}int sap(){    int res=0;    memset(gap,0,sizeof(gap));    memset(h,0,sizeof(h));    gap[0]=n;    while(h[src]<n)res+=dfs(src,INF);    return res;}vector<int>X,Y;map<pair<int,int>,int>mp;int dx[]={0,0,-1,1};int dy[]={-1,1,0,0};void build(int n,vector<int>&x,vector<int>&ans){set<int>st;for(int i=0;i<(int)x.size();i++){for(int j=max(1,x[i]-3);j<=min(n,x[i]+3);j++)st.insert(j);}for(set<int>::iterator it=st.begin();it!=st.end();++it)ans.push_back(*it);sort(ans.begin(),ans.end());return;}class FoxAndCake{public: string ableToDivide(int N, int M, vector <int> x, vector <int> y){build(N,x,X);build(M,y,Y);n=(int)X.size()*Y.size();src=0;des=2*n+1;int num=0;memset(head,-1,sizeof(head));tot=0;for(int i=0;i<(int)X.size();i++)for(int j=0;j<(int)Y.size();j++){mp[make_pair(X[i],Y[j])]=++num;//printf("id %d %d is %d\n",X[i],Y[j],num);}printf("%d\n",num);for(int i=1;i<=n;i++){if(mp[make_pair(x[0],y[0])]==i)continue;elseaddedge(i,i+n,1);}for(int i=1;i<4;i++){addedge(src,mp[make_pair(x[i],y[i])],1);}for(int i=4;i<7;i++){addedge(mp[make_pair(x[i],y[i])]+n,des,1);}for(int i=0;i<(int)X.size();i++)for(int j=0;j<(int)Y.size();j++){for(int k=0;k<4;k++){int ni=i+dx[k];int nj=j+dy[k];if(ni<0||ni>=(int)X.size())continue;if(nj<0||nj>=(int)Y.size())continue;addedge(mp[make_pair(X[i],Y[j])]+n,mp[make_pair(X[ni],Y[nj])],INF);}}n=des+1;int flow=sap();if(flow>=3)return "Yes";elsereturn "No";}};


0 0
原创粉丝点击