Escape HDU

来源:互联网 发布:前端js视频教程下载 编辑:程序博客网 时间:2024/06/05 16:31

2012 If this is the end of the world how to do? I do not know how. But now scientists have found that some stars, who can live, but some people do not fit to live some of the planet. Now scientists want your help, is to determine what all of people can live in these planets.
Input
More set of test data, the beginning of each data is n (1 <= n <= 100000), m (1 <= m <= 10) n indicate there n people on the earth, m representatives m planet, planet and people labels are from 0. Here are n lines, each line represents a suitable living conditions of people, each row has m digits, the ith digits is 1, said that a person is fit to live in the ith-planet, or is 0 for this person is not suitable for living in the ith planet.
The last line has m digits, the ith digit ai indicates the ith planet can contain ai people most..
0 <= ai <= 100000
Output
Determine whether all people can live up to these stars
If you can output YES, otherwise output NO.
Sample Input
1 1
1
1

2 2
1 0
1 0
1 1
Sample Output
YES
NO
这个题做了上一道,知道是用网络流的算法来解决了,就是按照正常思路来做了,后来发现超时了,我想一想,n这么大,我们每次增广的时候只能增广容量为1大小的值,也就是说n多大就要进行多次的bfs,后来想想某些人的对星球的选择意愿应该会相同,看到星球只有10个,那么最多只有210种意愿了,所有就是把某些相同选择的人的给压缩了,那么最多就是1024个人会和m个星球想练

#include<cstdio>#include<iostream>#include<queue>#include<cstring>using namespace std;int n,m;struct node1{    int to;    int cap;}edge[25000];int k;vector<int> graph[2000];int num[1030];void addEdge(int x,int y,int c){    edge[k].to=y;    edge[k].cap=c;    graph[x].push_back(k);    k++;    edge[k].to=x;    edge[k].cap=0;    graph[y].push_back(k);    k++;}struct node{    int now;    int lastIndex;    int index;    int minC;}que[30000];int head,tail;bool vis[2000];bool work(){    bool sign;    int ans=0;    node start;    node endd;    for(;;)    {        //cout<<"haha"<<endl;        memset(vis,false,sizeof(vis));        start.lastIndex=-1;        start.now=0;        start.minC=10000000;        head=tail=0;        que[tail++]=start;        sign=true;        vis[0]=true;        while(head<tail&&sign)        {            node temp=que[head++];            int u=temp.now;            for(int i=0;i<graph[u].size();i++)            {                int index=graph[u][i];                int v=edge[graph[u][i]].to;                if(vis[v]||edge[index].cap==0)                    continue;                if(v==(1<<m)+m)                {                    endd.index=index;                    endd.minC=min(edge[index].cap,temp.minC);                    endd.lastIndex=head-1;                    sign=false;                    break;                }                else                {                    vis[v]=true;                    node out;                    out.now=v;                    out.lastIndex=head-1;                    out.index=index;                    out.minC=min(edge[index].cap,temp.minC);                    que[tail++]=out;                }            }        }        if(sign)            break;        else        {            int cal=endd.minC;            ans+=cal;            while(endd.lastIndex!=-1)            {                int index=endd.index;                edge[index].cap-=cal;                edge[index^1].cap+=cal;                endd=que[endd.lastIndex];            }        }    }    //cout<<ans<<endl;    //cout<<total<<endl;    return ans==n;}int main(){   int a,b;   while(scanf("%d%d",&n,&m)==2)   {       for(int i=0;i<=(1<<m)+m;i++)            graph[i].clear();        memset(num,0,sizeof(num));       k=0;       int p=(1<<m)+m;       int state;       for(int i=1;i<=n;i++)       {           state=0;           for(int j=0;j<m;j++)           {                scanf("%d",&b);                if(b)                    state+=1<<j;//译码           }           num[state]++;       }       //cout<<"p:"<<p<<endl;       for(int s=1;s<(1<<m);s++)       {           if(num[s])           {               addEdge(0,s,num[s]);               for(int i=0;i<m;i++)                if((s>>i)&1)//解码                   addEdge(s,(1<<m)+i,num[s]);           }       }       for(int i=1;i<=m;i++)       {           scanf("%d",&b);           addEdge((1<<m)-1+i,p,b);       }       if(work())        printf("YES\n");       else        printf("NO\n");   }    return 0;}
原创粉丝点击