HDU-3605-Escape(最大流+状压)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605

题意:N(1<=N<=1e6)个人从earth去M(1<=M<=10)个星球,每个人只能去其适应的星球,每个星球有容量Vi(0<=Vi<=1e6).问是否都能离开earth

题解:

看起来很裸的最大流,N<=1e6   M<=10 但是显然N*M建边会超时(跑了一遍果然超了= =||)

由于1<<10大约1e4,所以直接把状态相同的people丢一块就可以啦。


//#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define INF 0x3f3f3f3f
#define bug cout<<"bug\n"
using namespace std;
const int MAXN = 1e5+20;
const int MAXM = 3e6+7;
const double eps = 1e-5;
int n,m;
struct node
{
    int v,next;
    int flow;
} edge[MAXM];
int head[MAXM],index;
int peo[1007];
void add_edge(int u,int v,int flow)
{
    edge[index].v=v;
    edge[index].flow=flow;
    edge[index].next=head[u];
    head[u]=index++;
    edge[index].v=u;
    edge[index].flow=0;
    edge[index].next=head[v];
    head[v]=index++;
}
int deep[MAXN];
bool BFS(int S, int T)
{
    memset(deep,0,sizeof(deep));
    deep[S]=1;
    queue q;
    q.push(S);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=head[u]; i+1; i=edge[i].next)
        {
            int v=edge[i].v;
            if(!deep[v] && edge[i].flow>0)
            {
                deep[v]=deep[u]+1;
                q.push(v);
                if(v==T)return 1;
            }
        }
    }
    return 0;
}
int DFS(int S, int T, int max_)
{
    if(S==T)return max_;
    int ans=0,f;
    for(int i=head[S]; i+1 ; i=edge[i].next)
    {
        int v=edge[i].v;
        if(deep[S]+1==deep[v] && edge[i].flow>0)
        {
            f=DFS(v,T,min(max_-ans,edge[i].flow));
            edge[i].flow-=f;
            edge[i^1].flow+=f;
            ans+=f;
        }
    }
    return ans;
}
int dinic(int S,int T)
{
    int ans=0,t;
    while(BFS(S,T))
        while(t=DFS(S,T,INF))
            ans+=t;
    return ans;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(head,-1,sizeof(head));
        memset(peo,0,sizeof(peo));
        index=0;
        int poi=0;
        for(int i=0; i>=1;
            }
        }
        int ans=dinic(0,t);
        if(ans>=n)printf("YES\n");
        else printf("NO\n");

///TLE
        /*
        int S=n+m,T=n+m+1,p;
        for(int i=0; i


你可能感兴趣的:(HDU,图论)