zoukankan      html  css  js  c++  java
  • HDU 3605 Escape (最大流+合并点)

    http://acm.hdu.edu.cn/showproblem.php?pid=3605

    注意n的范围是100000,m的范围是10,所以最多的情况是合并成2^10=1024个n

    先用map合并点,然后源点到n的容量设为p(表示这种点的数量),m到汇点的容量按题设

    然后求最大流即可

    PS:如果不合并点会TLE

      1 //#pragma comment(linker, "/STACK:102400000,102400000")
      2 #include<cstdio>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<string>
      6 #include<cmath>
      7 #include<set>
      8 #include<list>
      9 #include<map>
     10 #include<iterator>
     11 #include<cstdlib>
     12 #include<vector>
     13 #include<queue>
     14 #include<stack>
     15 #include<algorithm>
     16 #include<functional>
     17 using namespace std;
     18 typedef long long LL;
     19 #define ROUND(x) round(x)
     20 #define FLOOR(x) floor(x)
     21 #define CEIL(x) ceil(x)
     22 const int maxn=1200;
     23 const int maxm=200010;
     24 const int inf=0x3f3f3f3f;
     25 const LL inf64=0x3f3f3f3f3f3f3f3fLL;
     26 const double INF=1e30;
     27 const double eps=1e-6;
     28 
     29 /**
     30 *最大流最小割:加各种优化的Dinic算法($O(V^2E)$)
     31 *输入:图(链式前向星),n(顶点个数,包含源汇),st(源),ed(汇)
     32 *输出:Dinic(NdFlow)(最大流),MinCut()(最小割)(需先求最大流)
     33 *打印路径方法:按反向边(i&1)的flow 找,或者按边的flow找
     34 */
     35 //const int maxn=0;
     36 //const int maxm=0;
     37 //const int inf=0x3f3f3f3f;
     38 struct Edge
     39 {
     40     int u,v;
     41     int cap,flow;
     42     int next;
     43 } edge[maxm];
     44 int head[maxn],edgeNum;//需初始化
     45 int n,m,d[maxn],cur[maxn];
     46 int st,ed;
     47 bool vis[maxn];
     48 void addSubEdge(int u,int v,int cap,int flow)
     49 {
     50     edge[edgeNum].u=u;
     51     edge[edgeNum].v=v;
     52     edge[edgeNum].cap=cap;
     53     edge[edgeNum].flow=flow;
     54     edge[edgeNum].next=head[u];
     55     head[u]=edgeNum++;
     56     cur[u]=head[u];
     57 }
     58 void addEdge(int u,int v,int cap)
     59 {
     60     addSubEdge(u,v,cap,0);
     61     addSubEdge(v,u,0,0);//注意加反向0 边
     62 }
     63 bool BFS()
     64 {
     65     queue<int> Q;
     66     memset(vis, 0, sizeof(vis));
     67     Q.push(st);
     68     d[st]=0;
     69     vis[st]=1;
     70     while (!Q.empty())
     71     {
     72         int u=Q.front();
     73         Q.pop();
     74         for(int i=head[u]; i!=-1; i=edge[i].next)
     75         {
     76             int v=edge[i].v;
     77             int w=edge[i].cap-edge[i].flow;
     78             if(w>0 && !vis[v])
     79             {
     80                 vis[v]=1;
     81                 Q.push(v);
     82                 d[v]=d[u]+1;
     83                 if(v==ed) return 1;
     84             }
     85         }
     86     }
     87     return false;
     88 }
     89 int Aug(int u, int a)
     90 {
     91     if (u==ed) return a;
     92     int aug=0, delta;
     93     for(int &i=cur[u]; i!=-1; i=edge[i].next)
     94     {
     95         int v=edge[i].v;
     96         int w=edge[i].cap-edge[i].flow;
     97         if (w>0 && d[v]==d[u]+1)
     98         {
     99             delta = Aug(v, min(a,w));
    100             if (delta)
    101             {
    102                 edge[i].flow += delta;
    103                 edge[i^1].flow -= delta;
    104                 aug += delta;
    105                 if (!(a-=delta)) break;
    106             }
    107         }
    108     }
    109     if (!aug) d[u]=-1;
    110     return aug;
    111 }
    112 int Dinic(int NdFlow)
    113 {
    114     int flow=0;
    115     while (BFS())
    116     {
    117         memcpy(cur,head,sizeof(int)*(n+1));
    118         flow += Aug(st,inf);
    119         /*如果超过指定流量就return 掉*/
    120         if(NdFlow==inf) continue;
    121         if(flow > NdFlow) break;
    122     }
    123     return flow;
    124 }
    125 
    126 map<string,int> mp;
    127 map<string,int>::iterator ite;
    128 int N,M;
    129 char strx[110];
    130 int num[20];
    131 void init()
    132 {
    133     memset(head,-1,sizeof(head));
    134     edgeNum=0;
    135     mp.clear();
    136 }
    137 void input()
    138 {
    139     if(scanf("%d%d",&N,&M)==EOF) exit(0);
    140     getchar();
    141     for(int i=0;i<N;i++)
    142     {
    143         gets(strx);
    144         string str=strx;
    145         mp[str]++;
    146     }
    147     for(int i=0;i<M;i++) scanf("%d",&num[i]);
    148 }
    149 void build()
    150 {
    151     n=mp.size()+M+2;
    152     st=0,ed=mp.size()+M+1;
    153     int i;
    154     for(ite=mp.begin(),i=1;ite!=mp.end();ite++,i++)
    155     {
    156         addEdge(st,i,ite->second);
    157         int m=1;
    158         for(int j=0;j<ite->first.size();j++)
    159         {
    160             if(ite->first[j]=='1')
    161             {
    162                 addEdge(i,mp.size()+m,ite->second);
    163             }
    164             if(ite->first[j]=='0'||ite->first[j]=='1')
    165             {
    166                 m++;
    167             }
    168         }
    169     }
    170     for(i=mp.size()+1;i<=mp.size()+M;i++)
    171     {
    172         addEdge(i,ed,num[i-(mp.size()+1)]);
    173     }
    174 }
    175 void solve()
    176 {
    177     build();
    178     if(Dinic(inf)==N) puts("YES");
    179     else puts("NO");
    180 //    printf("%d
    ",Dinic(inf));
    181 }
    182 void output()
    183 {
    184     //
    185 }
    186 int main()
    187 {
    188 //    std::ios_base::sync_with_stdio(false);
    189 //    freopen("in.cpp","r",stdin);
    190     while(1)
    191     {
    192         init();
    193         input();
    194         solve();
    195         output();
    196     }
    197     return 0;
    198 }
    View Code
  • 相关阅读:
    单独设置css的class属性
    理解闭包的使用方法
    npm常用命令和总结
    前端调试之服务器
    gulp 报错的处理——个人经验
    工作经验备忘
    c++:虚函数和纯虚函数(转载)
    snmp学习、配置
    sigar学习
    linux安装VSCode
  • 原文地址:https://www.cnblogs.com/xysmlx/p/3365287.html
Copyright © 2011-2022 走看看