2017百度之星资格赛1002:度度熊的王国战略(最小割)

很大胆的用了最小割  可能因为数据太水 5000+ms过的

也根据这个道题仔细想了想最小割 其实最小割就是把一个连通块分为两部分

思路:

最小割其实就是把一个连通块分成两部分

只不过我们之前做的最小割 比如求从节点1号到节点n号的最小割 割完边后图肯定是分成了两部分 而且1号与n号肯定不在同一部分 

这题没有具体要求哪两个点要分开 只要分成两部分就好

所以 只要图被分成了两部分 n号节点肯定在其中一部分 那么肯定存在某个点x在另一部分 这个最小割就是x号到n号的最小割

所以我们只要将源点从1一直赋值到n-1  进行n-1次循环去求最小的最小割就好了 


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long ll;
using namespace std;
const int MAXN=20010;
const int MAXM=880010;
const int INF=0x3f3f3f3f;
int bian[100005][3];//用来存m组边
int used[3000];//use[i]==0代表i这个节点从未出现过 ==1代表已经出现过了
struct Node
{
    int from,to,next;
    int cap;
}edge[MAXM];
int tol;
int head[MAXN];
int dep[MAXN];
int gap[MAXN];



void init()  
{
    tol=0;
    memset(head,-1,sizeof(head));
}

void addedge(int u,int v,int w)
{
    edge[tol].from=u;
    edge[tol].to=v;
    edge[tol].cap=w;
    edge[tol].next=head[u];
    head[u]=tol++;
    edge[tol].from=v;
    edge[tol].to=u;
    edge[tol].cap=w;//无向图 
    edge[tol].next=head[v];
    head[v]=tol++;
}
void BFS(int start,int end)
{
    memset(dep,-1,sizeof(dep));
    memset(gap,0,sizeof(gap));
    gap[0]=1;
    int que[MAXN];
    int front,rear;
    front=rear=0;
    dep[end]=0;
    que[rear++]=end;
    while(front!=rear)
    {
        int u=que[front++];
        if(front==MAXN)front=0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if(dep[v]!=-1)continue;
            que[rear++]=v;
            if(rear==MAXN)rear=0;
            dep[v]=dep[u]+1;
            ++gap[dep[v]];
        }
    }
}
int SAP(int start,int end,int n) //n 为节点的个数
{
    int res=0;
    BFS(start,end);
    int cur[MAXN];
    int S[MAXN];
    int top=0;
    memcpy(cur,head,sizeof(head));
    int u=start;
    int i;
    while(dep[start]edge[S[i]].cap)
                {
                    temp=edge[S[i]].cap;
                    inser=i;
                }
            for(i=0;idep[edge[i].to])
                {
                    min=dep[edge[i].to];
                    cur[u]=i;
                }
            }
            --gap[dep[u]];
            dep[u]=min+1;
            ++gap[dep[u]];
            if(u!=start)u=edge[S[--top]].from;
        }
    }
    return res;
}
void getmap(int m)
{
    init();
    int i;
    for(i=0;i


你可能感兴趣的:(ACM,最大流)