• 最大流


    刚刚学了两个最大流算法Dinic和ISAP,很多地方不是很清楚=_=||

    先刷些题练练吧

    Drainage Ditches

     HDU - 1532 
    题意:求1到n的最大流,裸题

    可以说是模板题了,用Dinic做的

    我把Lrj的模板改了下,个人不太喜欢用vector==

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define CLR(m,a) memset(m,a,sizeof(m))
      4 const int inf=0x3f3f3f3f;
      5 const int maxv=210;
      6 int n,m;
      7 struct Edge
      8 {
      9     int u,v,cap,flow;
     10     int nex;
     11 }e[maxv<<1];
     12 int head[maxv];
     13 int cnt=0;
     14 void init()
     15 {
     16     CLR(head,-1);
     17     cnt=0;
     18 }
     19 void add(int u,int v,int cap)
     20 {
     21     e[cnt].u=u;
     22     e[cnt].v=v;
     23     e[cnt].cap=cap;
     24     e[cnt].flow=0;
     25     e[cnt].nex=head[u];
     26     head[u]=cnt++;
     27 }
     28 
     29 int vis[maxv],d[maxv],cur[maxv];
     30 int s,t;
     31 int bfs()
     32 {
     33     CLR(vis,0);
     34     queue<int> q;
     35     q.push(s);
     36     d[s]=0;
     37     vis[s]=1;
     38     while(!q.empty())
     39     {
     40         int u=q.front();
     41         q.pop();
     42         for(int i=head[u];~i;i=e[i].nex)
     43         {
     44             int v=e[i].v;
     45             if(!vis[v]&&e[i].cap>e[i].flow)
     46             {
     47                 vis[v]=1;
     48                 d[v]=d[u]+1;
     49                 q.push(v);
     50             }
     51         }
     52     }
     53     return vis[t];
     54 }
     55 
     56 int dfs(int x,int a)
     57 {
     58     if(x==t||a==0) return a;
     59     int flow=0,f;
     60     for(int &i=cur[x];~i;i=e[i].nex)
     61     {
     62         int v=e[i].v;
     63         if(d[x]+1==d[v]&&(f=dfs(v,min(a,e[i].cap-e[i].flow)))>0)
     64         {
     65             e[i].flow+=f;
     66             e[i^1].flow-=f;
     67             flow+=f;
     68             a-=f;
     69             if(a==0) break;
     70         }
     71     }
     72     return flow;
     73 }
     74 
     75 int Maxflow()
     76 {
     77     int flow=0;
     78     while(bfs())
     79     {
     80         for(int i=0;i<n;i++) cur[i]=head[i];
     81         flow+=dfs(s,inf);
     82     }
     83     return flow;
     84 }
     85 
     86 int main()
     87 {
     88     while(scanf("%d%d",&m,&n)!=EOF)
     89     {
     90         init();
     91         int u,v,cap;
     92         for(int i=0;i<m;i++)
     93         {
     94             scanf("%d%d%d",&u,&v,&cap);
     95             u--;v--;
     96             add(u,v,cap);
     97             add(v,u,0);
     98         }
     99         s=0;t=n-1;  //
    100         printf("%d
    ",Maxflow());
    101     }
    102 }
    View Code

    Flow Problem

     HDU - 3549 
    题意:求1到n的最大流,裸题

     本来想着练习一下ISPA

    结果。。悲剧了一晚上。。。

    代码里面有注释,关键点在更新m时判断一下d[v]是否可达,lrj的书里面没提到。。。

    好像跟d的初始化有关。。。

    再加上我用前向星存的边,出了点差错,单行调试了一上午才发现=_=||

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define CLR(m,a) memset(m,a,sizeof(m))
      4 const int inf=0x3f3f3f3f;
      5 const int maxv=20;
      6 const int maxe=1010;
      7 int n,m;
      8 struct Edge
      9 {
     10     int u,v,cap,flow;
     11     int nex;
     12 }e[maxe<<1];
     13 int head[maxv];
     14 int cnt=0;
     15 void init()
     16 {
     17     CLR(head,-1);
     18     cnt=0;
     19 }
     20 void add(int u,int v,int cap)
     21 {
     22     e[cnt].u=u;
     23     e[cnt].v=v;
     24     e[cnt].cap=cap;
     25     e[cnt].flow=0;
     26     e[cnt].nex=head[u];
     27     head[u]=cnt++;
     28 }
     29 
     30 int p[maxv];   // 可增广路上的上一条弧的编号
     31 int num[maxv]; // 和 t 的最短距离等于 i 的节点数量
     32 int cur[maxv];// 当前弧下标
     33 int d[maxv]; // 残量网络中节点 i 到汇点 t 的最短距离
     34 int vis[maxv];
     35 int s,t;
     36 
     37 // 预处理, 反向 BFS 构造 d 数组
     38 int bfs()
     39 {
     40     CLR(vis,0);
     41     CLR(d,-1);
     42     queue<int> q;
     43     while(!q.empty()) q.pop();
     44     q.push(t);
     45     vis[t]=1;
     46     d[t]=0;
     47     while(!q.empty())
     48     {
     49         int u=q.front();
     50         q.pop();
     51         for(int i=head[u];~i;i=e[i].nex)
     52         {
     53             int id=i&(-2);
     54             int v=e[id].u;
     55             if(!vis[v]&&e[id].cap>e[id].flow)
     56             {
     57                 vis[v]=1;
     58                 d[v]=d[u]+1;
     59                 q.push(v);
     60             }
     61         }
     62     }
     63     return vis[s];
     64 }
     65 
     66 //增广
     67 int augment()
     68 {
     69     int u=t,a=inf;
     70     while(u!=s)
     71     {
     72         int id=p[u];
     73         a=min(a,e[id].cap-e[id].flow);
     74         u=e[id].u;
     75     }
     76     u=t;
     77     while(u!=s)
     78     {
     79         int id=p[u];
     80         e[id].flow+=a;
     81         e[id^1].flow-=a;
     82         u=e[id].u;
     83     }
     84     return a;
     85 }
     86 
     87 int Maxflow()
     88 {
     89     bfs();
     90     int flow=0;
     91     CLR(num,0);
     92     for(int i=0;i<n;i++) num[d[i]]++;
     93     int u=s;
     94     for(int i=0;i<n;i++) cur[i]=head[i];
     95     while(d[s]<n)
     96     {
     97         if(u==t)
     98         {
     99             flow+=augment();
    100             u=s;
    101         }
    102         int ok=0;
    103         for(int i=cur[u];~i;i=e[i].nex)
    104         {
    105             int v=e[i].v;
    106             if(e[i].cap>e[i].flow&&d[u]==d[v]+1)
    107             {
    108                 ok=1;
    109                 p[v]=i;
    110                 cur[u]=i;
    111                 u=v;
    112                 break;
    113             }
    114         }
    115         if(!ok)
    116         {
    117             int m=n-1;
    118             for(int i=head[u];~i;i=e[i].nex)
    119             {
    120                 int v=e[i].v;
    121                 if(e[i].cap>e[i].flow&&d[v]!=-1) m=min(m,d[v]);
    122             }
    123             if(--num[d[u]]==0) break;  //gap优化
    124             num[d[u]=m+1]++;
    125             cur[u]=head[u];
    126             if(u!=s) u=e[p[u]].u;
    127         }
    128     }
    129     return flow;
    130 }
    131 
    132 int main()
    133 {
    134     int tt;
    135     int kase=0;
    136     scanf("%d",&tt);
    137     while(tt--)
    138     {
    139         init();
    140         int u,v,cap;
    141         scanf("%d%d",&n,&m);
    142         for(int i=0;i<m;i++)
    143         {
    144             scanf("%d%d%d",&u,&v,&cap);
    145             u--;v--;
    146             add(u,v,cap);
    147             add(v,u,0);
    148         }
    149         s=0;t=n-1;
    150         printf("Case %d: %d
    ",++kase,Maxflow());
    151     }
    152 }
    View Code
      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define CLR(m,a) memset(m,a,sizeof(m))
      4 const int inf=0x3f3f3f3f;
      5 const int maxv=20;
      6 const int maxe=1010;
      7 int n,m;
      8 struct Edge
      9 {
     10     int u,v,cap,flow;
     11     int nex;
     12 }e[maxe<<1];
     13 int head[maxv];
     14 int cnt=0;
     15 void init()
     16 {
     17     CLR(head,-1);
     18     cnt=0;
     19 }
     20 void add(int u,int v,int cap)
     21 {
     22     e[cnt].u=u;
     23     e[cnt].v=v;
     24     e[cnt].cap=cap;
     25     e[cnt].flow=0;
     26     e[cnt].nex=head[u];
     27     head[u]=cnt++;
     28 }
     29 
     30 int p[maxv];   // 可增广路上的上一条弧的编号
     31 int num[maxv]; // 和 t 的最短距离等于 i 的节点数量
     32 int cur[maxv];// 当前弧下标
     33 int d[maxv]; // 残量网络中节点 i 到汇点 t 的最短距离
     34 int vis[maxv];
     35 int s,t;
     36 
     37 // 预处理, 反向 BFS 构造 d 数组
     38 int bfs()
     39 {
     40     CLR(vis,0);
     41    // CLR(d,-1);   //!!!
     42     queue<int> q;
     43     while(!q.empty()) q.pop();
     44     q.push(t);
     45     vis[t]=1;
     46     d[t]=0;
     47     while(!q.empty())
     48     {
     49         int u=q.front();
     50         q.pop();
     51         for(int i=head[u];~i;i=e[i].nex)
     52         {
     53             int id=i&(-2);
     54             int v=e[id].u;
     55             if(!vis[v]&&e[id].cap>e[id].flow)
     56             {
     57                 vis[v]=1;
     58                 d[v]=d[u]+1;
     59                 q.push(v);
     60             }
     61         }
     62     }
     63     return vis[s];
     64 }
     65 
     66 //增广
     67 int augment()
     68 {
     69     int u=t,a=inf;
     70     while(u!=s)
     71     {
     72         int id=p[u];
     73         a=min(a,e[id].cap-e[id].flow);
     74         u=e[id].u;
     75     }
     76     u=t;
     77     while(u!=s)
     78     {
     79         int id=p[u];
     80         e[id].flow+=a;
     81         e[id^1].flow-=a;
     82         u=e[id].u;
     83     }
     84     return a;
     85 }
     86 
     87 int Maxflow()
     88 {
     89     bfs();
     90     int flow=0;
     91     CLR(num,0);
     92     for(int i=0;i<n;i++) num[d[i]]++;
     93     int u=s;
     94     for(int i=0;i<n;i++) cur[i]=head[i];
     95     while(d[s]<n)
     96     {
     97         if(u==t)
     98         {
     99             flow+=augment();
    100             u=s;
    101         }
    102         int ok=0;
    103         for(int i=cur[u];~i;i=e[i].nex)
    104         {
    105             int v=e[i].v;
    106             if(e[i].cap>e[i].flow&&d[u]==d[v]+1)
    107             {
    108                 ok=1;
    109                 p[v]=i;
    110                 cur[u]=i;
    111                 u=v;
    112                 break;
    113             }
    114         }
    115         if(!ok)
    116         {
    117             int m=n-1;
    118             for(int i=head[u];~i;i=e[i].nex)
    119             {
    120                 int v=e[i].v;
    121                 if(e[i].cap>e[i].flow/*&&d[v]!=-1*/) m=min(m,d[v]);   //关键点!!!注释掉就错啦
    122             }
    123             if(--num[d[u]]==0) break;  //gap优化
    124             num[d[u]=m+1]++;
    125             cur[u]=head[u];
    126             if(u!=s) u=e[p[u]].u;
    127         }
    128     }
    129     return flow;
    130 }
    131 
    132 int main()
    133 {
    134     int tt;
    135     int kase=0;
    136     scanf("%d",&tt);
    137     while(tt--)
    138     {
    139         init();
    140         int u,v,cap;
    141         scanf("%d%d",&n,&m);
    142         for(int i=0;i<m;i++)
    143         {
    144             scanf("%d%d%d",&u,&v,&cap);
    145             u--;v--;
    146             add(u,v,cap);
    147             add(v,u,0);
    148         }
    149         s=0;t=n-1;
    150         printf("Case %d: %d
    ",++kase,Maxflow());
    151     }
    152 }
    153 /*
    154 5 6
    155 1 2 40
    156 1 5 20
    157 2 5 20
    158 2 3 30
    159 3 5 10
    160 2 4 10
    161 */
    error

     补一个低效但相对简单易懂的算法Edmonds-Karp

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxv=20;
     4 const int maxe=1010;
     5 const int inf=0x3f3f3f3f;
     6 #define CLR(m,a) memset(m,a,sizeof(m))
     7 int n,m;
     8 struct Edge
     9 {
    10     int u,v,cap,flow;
    11     int nex;
    12 }e[maxe<<1];
    13 int head[maxv];
    14 int cnt=0;
    15 void init()
    16 {
    17     CLR(head,-1);
    18     cnt=0;
    19 }
    20 void add(int u,int v,int cap)
    21 {
    22     e[cnt].u=u;
    23     e[cnt].v=v;
    24     e[cnt].flow=0;
    25     e[cnt].cap=cap;
    26     e[cnt].nex=head[u];
    27     head[u]=cnt++;
    28 }
    29 int s,t;
    30 int a[maxv],p[maxv];
    31 int EK()
    32 {
    33     int flow=0;
    34     for(;;)
    35     {
    36         CLR(a,0);
    37         queue<int> q;
    38         q.push(s);
    39         a[s]=inf;
    40         while(!q.empty())
    41         {
    42             int u=q.front();
    43             q.pop();
    44             for(int i=head[u];~i;i=e[i].nex)
    45             {
    46                 int v=e[i].v;
    47                 if(!a[v]&&e[i].cap>e[i].flow)
    48                 {
    49                     p[v]=i;
    50                     a[v]=min(a[u],e[i].cap-e[i].flow);
    51                     q.push(v);
    52                 }
    53             }
    54             if(a[t]) break;
    55         }
    56         if(!a[t]) break;
    57         for(int u=t;u!=s;u=e[p[u]].u)
    58         {
    59             e[p[u]].flow+=a[t];
    60             e[p[u]^1].flow-=a[t];
    61         }
    62         flow+=a[t];
    63     }
    64     return flow;
    65 }
    66 int main()
    67 {
    68     int tt;
    69     int kase=0;
    70     scanf("%d",&tt);
    71     while(tt--)
    72     {
    73         init();
    74         int u,v,cap;
    75         scanf("%d%d",&n,&m);
    76         for(int i=0;i<m;i++)
    77         {
    78             scanf("%d%d%d",&u,&v,&cap);
    79             u--;v--;
    80             add(u,v,cap);
    81             add(v,u,0);
    82         }
    83         s=0;t=n-1;
    84         printf("Case %d: %d
    ",++kase,EK());
    85     }
    86 }
    一般不用,效率低

    Task Schedule

     HDU - 3572 
    题意:要加工n个零件,每个零件要加工pi天,只能在si到ti之间加工,每天最多只能加工m个,问是否可以完工

    加超级源和超级汇

    本来建图能力就差,根本没想到

    超级源到每一个零件连一条权重为pi的边,每个零件到可以加工的时间(每一天)连一条为1的边

    时间(每一天)到超级汇连一条为m的边

    其实还是比较好理解的

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define CLR(m,a) memset(m,a,sizeof(m))
      4 const int inf=0x3f3f3f3f;
      5 const int maxv=510;
      6 int n,m;
      7 struct Edge
      8 {
      9     int u,v,cap,flow;
     10     int nex;
     11 }e[(maxv*maxv<<1)+2010];
     12 int head[maxv<<1];
     13 int cnt=0;
     14 void init()
     15 {
     16     CLR(head,-1);
     17     cnt=0;
     18 }
     19 void add(int u,int v,int cap)
     20 {
     21     e[cnt].u=u;
     22     e[cnt].v=v;
     23     e[cnt].cap=cap;
     24     e[cnt].flow=0;
     25     e[cnt].nex=head[u];
     26     head[u]=cnt++;
     27 }
     28 int num[maxv<<1],d[maxv<<1],p[maxv<<1],vis[maxv<<1],cur[maxv<<1];
     29 int s,t;
     30 int bfs()
     31 {
     32     CLR(vis,0);
     33     CLR(d,-1);
     34     queue<int> q;
     35     q.push(t);
     36     d[t]=0;
     37     vis[t]=1;
     38     while(!q.empty())
     39     {
     40         int u=q.front();
     41         q.pop();
     42         for(int i=head[u];~i;i=e[i].nex)
     43         {
     44             int id=i&(-2);
     45             int v=e[id].u;
     46             if(!vis[v]&&e[id].cap>e[id].flow)
     47             {
     48                 vis[v]=1;
     49                 d[v]=d[u]+1;
     50                 q.push(v);
     51             }
     52         }
     53     }
     54     return vis[s];
     55 }
     56 int augment()
     57 {
     58     int u=t,a=inf;
     59     while(u!=s)
     60     {
     61         int id=p[u];
     62         a=min(a,e[id].cap-e[id].flow);
     63         u=e[id].u;
     64     }
     65     u=t;
     66     while(u!=s)
     67     {
     68         int id=p[u];
     69         e[id].flow+=a;
     70         e[id^1].flow-=a;
     71         u=e[id].u;
     72     }
     73     return a;
     74 }
     75 int ISAP()
     76 {
     77     bfs();
     78     int flow=0;
     79     CLR(num,0);
     80     for(int i=0;i<n;i++) num[d[i]]++;
     81     for(int i=0;i<n;i++) cur[i]=head[i];
     82     int u=s;
     83     while(d[s]<n)
     84     {
     85         if(u==t)
     86         {
     87             flow+=augment();
     88             u=s;
     89         }
     90         int ok=0;
     91         for(int i=cur[u];~i;i=e[i].nex)
     92         {
     93             int v=e[i].v;
     94             if(e[i].cap>e[i].flow&&d[u]==d[v]+1)
     95             {
     96                 ok=1;
     97                 p[v]=i;
     98                 cur[u]=i;
     99                 u=v;
    100                 break;
    101             }
    102         }
    103         if(!ok)
    104         {
    105             int m=n-1;
    106             for(int i=head[u];~i;i=e[i].nex)
    107                 if(e[i].cap>e[i].flow&&d[e[i].v]!=-1) m=min(m,d[e[i].v]);
    108             if(--num[d[u]]==0) break;
    109             num[d[u]=m+1]++;
    110             cur[u]=head[u];
    111             if(u!=s) u=e[p[u]].u;
    112         }
    113     }
    114     return flow;
    115 }
    116 int main()
    117 {
    118     int tt;
    119     int kase=0;
    120     scanf("%d",&tt);
    121     while(tt--)
    122     {
    123         init();
    124         int si,pi,ei;
    125         int sum=0;
    126         int maxt=0;
    127         s=0;
    128         scanf("%d%d",&n,&m);
    129         for(int i=1;i<=n;i++)
    130         {
    131             scanf("%d%d%d",&pi,&si,&ei);
    132             maxt=max(maxt,ei);
    133             sum+=pi;
    134             add(s,i,pi);
    135             add(i,s,0);
    136             for(int j=si;j<=ei;j++)
    137             {
    138                 add(i,n+j,1);
    139                 add(j+n,i,0);
    140             }
    141         }
    142         t=n+maxt+1;
    143         for(int i=1;i<=maxt;i++)
    144         {
    145             add(i+n,t,m);
    146             add(t,i+n,0);
    147         }
    148         n=t+1;  //此处修改n值以适应模板
    149         printf("Case %d: ",++kase);
    150         if(ISAP()==sum) puts("Yes
    ");
    151         else puts("No
    ");
    152     }
    153 }
    View Code

    Leapin' Lizards

     HDU - 2732

     题意:在一个网格状的区域内,有一些柱子,并且这些柱子有一定的允许跳跃次数,有的柱子上有人,人有最大跳跃距离(曼哈顿距离)

        问有几个人无法跳出此区域

    还是不会建图啊,拆点!!!

    增加超级源和超级汇

    对于每一个人,从超级源到人连一条为1的边,对于任意两个可达的柱子,连一条无穷大的边,可跳出区域的柱子连一条无穷大的边到超级汇

    然后拆点,把每个柱子拆成两个,连一条为跳跃次数的边。

    拆点的意义在于限流!!!

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int inf=0x3f3f3f3f;
      4 const int maxv=1010;
      5 const int maxe=1000010;
      6 #define CLR(m,a) memset(m,a,sizeof(m))
      7 #define LL long long
      8 
      9 struct Edge
     10 {
     11     int u,v,cap,flow;
     12     int nex;
     13 }e[maxe<<1];
     14 int head[maxv];
     15 int cnt=0;
     16 void init()
     17 {
     18     CLR(head,-1);
     19     cnt=0;
     20 }
     21 void add(int u,int v,int cap)
     22 {
     23     e[cnt].u=u; e[cnt].v=v;
     24     e[cnt].cap=cap; e[cnt].flow=0;
     25     e[cnt].nex=head[u]; head[u]=cnt++;
     26 
     27     e[cnt].u=v; e[cnt].v=u;
     28     e[cnt].cap=0; e[cnt].flow=0;
     29     e[cnt].nex=head[v]; head[v]=cnt++;
     30 }
     31 char g1[25][25],g2[25][25];
     32 
     33 int n;
     34 int s,t;
     35 int p[maxv],cur[maxv],d[maxv],vis[maxv],num[maxv];
     36 void bfs()
     37 {
     38     CLR(vis,0);
     39     CLR(d,-1);
     40     queue<int> q;
     41     q.push(t);
     42     d[t]=0;
     43     vis[t]=1;
     44     while(!q.empty())
     45     {
     46         int u=q.front();
     47         q.pop();
     48         for(int i=head[u];~i;i=e[i].nex)
     49         {
     50             int id=i&(-2);
     51             int v=e[id].u;
     52             if(!vis[v]&&e[id].cap>e[id].flow)
     53             {
     54                 d[v]=d[u]+1;
     55                 vis[v]=1;
     56                 q.push(v);
     57             }
     58         }
     59     }
     60 }
     61 int augment()
     62 {
     63     int u=t,a=inf;
     64     while(u!=s)
     65     {
     66         int id=p[u];
     67         a=min(a,e[id].cap-e[id].flow);
     68         u=e[id].u;
     69     }
     70     u=t;
     71     while(u!=s)
     72     {
     73         int id=p[u];
     74         e[id].flow+=a;
     75         e[id^1].flow-=a;
     76         u=e[id].u;
     77     }
     78     return a;
     79 }
     80 int ISAP()
     81 {
     82     int flow=0;
     83     bfs();
     84     CLR(num,0);
     85     for(int i=0;i<n;i++){
     86         num[d[i]]++;
     87         cur[i]=head[i];
     88     }
     89     int u=s;
     90     while(d[s]<n){
     91         if(u==t){
     92             flow+=augment();
     93             u=s;
     94         }
     95         int ok=0;
     96         for(int i=cur[u];~i;i=e[i].nex){
     97             int v=e[i].v;
     98             if(e[i].cap>e[i].flow&&d[u]==d[v]+1){
     99                 ok=1;
    100                 p[v]=i;
    101                 cur[u]=i;
    102                 u=v;
    103                 break;
    104             }
    105         }
    106         if(!ok){
    107             int m=n-1;
    108             for(int i=head[u];~i;i=e[i].nex){
    109                 int v=e[i].v;
    110                 if(e[i].cap>e[i].flow&&d[v]!=-1) m=min(m,d[v]);
    111             }
    112             if(--num[d[u]]==0) break;
    113             num[d[u]=m+1]++;
    114             cur[u]=head[u];
    115             if(u!=s) u=e[p[u]].u;
    116         }
    117     }
    118     return flow;
    119 }
    120 int main()
    121 {
    122     int tt;
    123     int kase=0;
    124     scanf("%d",&tt);
    125     while(tt--){
    126         init();
    127         int r,c,dis;
    128         int sum=0;
    129         scanf("%d%d",&r,&dis);
    130         for(int i=0;i<r;i++){
    131             scanf("%s",g1[i]);
    132         }
    133         for(int i=0;i<r;i++){
    134             scanf("%s",g2[i]);
    135         }
    136         c=strlen(g1[0]);
    137         int py=r*c;  //拆点
    138         s=0;
    139         for(int i=0;i<r;i++){
    140             for(int j=0;j<c;j++){
    141                 int id=i*c+j+1;
    142                 if(g2[i][j]=='L'){
    143                     sum++;
    144                     add(s,id,1);
    145                 }
    146                 if(g1[i][j]!='0'){
    147                     add(id,id+py,g1[i][j]-'0');
    148                     if(i-dis<0||i+dis>=r||j-dis<0||j+dis>=c){
    149                         add(id+py,py*2+1,inf);
    150                     }
    151                     else{
    152                         for(int x=0;x<r;x++)
    153                         for(int y=0;y<c;y++){
    154                             if(x==i&&y==j) continue;
    155                             if(g1[x][y]!='0'){
    156                                 if(abs(x-i)+abs(y-j)<=dis){
    157                                     int newid=x*c+y+1;
    158                                     add(id+py,newid,inf);
    159                                 }
    160                             }
    161                         }
    162                     }
    163                 }
    164             }
    165         }
    166         s=0;t=py*2+1;n=t+1; //!!!
    167         int flow=ISAP();
    168         printf("Case #%d: ",++kase);
    169         if(flow==sum) puts("no lizard was left behind.");
    170         else if(flow+1==sum) puts("1 lizard was left behind.");
    171         else printf("%d lizards were left behind.
    ",sum-flow);
    172     }
    173     return 0;
    174 }
    View Code

    Kakuro Extension

     HDU - 3338 

    TLE到爆炸!!!很烦!!!实在看不下去了。。。。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int inf=0x3f3f3f3f;
      4 const int maxv=200010;
      5 const int maxe=1000010;  //
      6 #define CLR(m,a) memset(m,a,sizeof(m))
      7 
      8 int n,m,s,t;
      9 int tot;
     10 struct Edge{
     11     int u,v,cap,flow;
     12     int nex;
     13 }e[maxe];
     14 int head[maxv];
     15 int cnt=0;
     16 void init(){
     17     CLR(head,-1);
     18     cnt=0;
     19 }
     20 void add(int u,int v,int cap)
     21 {
     22     e[cnt].u=u; e[cnt].v=v;
     23     e[cnt].cap=cap; e[cnt].flow=0;
     24     e[cnt].nex=head[u]; head[u]=cnt++;
     25 
     26     e[cnt].u=v; e[cnt].v=u;
     27     e[cnt].cap=0; e[cnt].flow=0;
     28     e[cnt].nex=head[v]; head[v]=cnt++;
     29 }
     30 struct node{
     31     int id,cid,rid,sumc,sumr,type;
     32 }mp[105][105];
     33 int ans[105][105]; //记录该点的出边,便于输出
     34 
     35 int vis[maxv],cur[maxv],num[maxv],d[maxv],p[maxv];
     36 
     37 void bfs(){
     38     CLR(d,-1);
     39     CLR(vis,0);
     40     queue<int> q;
     41     q.push(t);
     42     d[t]=0;
     43     vis[t]=1;
     44     while(!q.empty()){
     45         int u=q.front();
     46         q.pop();
     47         for(int i=head[u];~i;i=e[i].nex){
     48             int id=i&(-2);
     49             int v=e[id].u;
     50             if(!vis[v]&&e[id].cap>e[id].flow){
     51                 vis[v]=1;
     52                 q.push(v);
     53                 d[v]=d[u]+1;
     54             }
     55         }
     56     }
     57 }
     58 int augment(){
     59     int a=inf,u=t;
     60     while(u!=s){
     61         int id=p[u];
     62         a=min(a,e[id].cap-e[id].flow);
     63         u=e[id].u;
     64     }
     65     u=t;
     66     while(u!=s){
     67         int id=p[u];
     68         e[id].flow+=a;
     69         e[id^1].flow-=a;
     70         u=e[id].u;
     71     }
     72     return a;
     73 }
     74 int ISAP(){
     75     bfs();
     76     int flow=0;
     77     CLR(num,0);
     78     for(int i=0;i<tot;i++){
     79         num[d[i]]++;
     80         cur[i]=head[i];
     81     }
     82     int u=s;
     83     while(d[s]<tot)
     84     {
     85         if(u==t)
     86         {
     87             flow+=augment();
     88             u=s;
     89         }
     90         int ok=0;
     91         for(int i=cur[u];~i;i=e[i].nex){
     92             int v=e[i].v;
     93             if(e[i].cap>e[i].flow&&d[u]==d[v]+1){
     94                 ok=1;
     95                 cur[u]=i;
     96                 p[v]=i;
     97                 u=v;
     98                 break;
     99             }
    100         }
    101         if(!ok){
    102             int m=tot-1;
    103             if(--num[d[u]]==0) break;
    104             for(int i=head[u];~i;i=e[i].nex){
    105                 int v=e[i].v;
    106                 if(e[i].cap>e[i].flow&&d[v]!=-1) m=min(m,d[v]);
    107             }
    108             num[d[u]=m+1]++;
    109             cur[u]=head[u];
    110             if(u!=s) u=e[p[u]].u;
    111         }
    112     }
    113     return flow;
    114 }
    115 
    116 int main(){
    117     while(scanf("%d%d",&n,&m)!=EOF){
    118         init();
    119         char c[10];
    120         int rowcnt=0,colcnt=0,white=0;
    121         for(int i=0;i<n;i++)
    122         for(int j=0;j<m;j++){
    123             scanf("%s",c);
    124             if(c[3]=='X') continue;
    125             else if(c[3]=='.'){
    126                 white++;
    127                 mp[i][j].type=2;
    128                 mp[i][j].id=white;
    129             }
    130             else{
    131                 mp[i][j].type=1;
    132                 int num;
    133                 if(c[0]!='X'){
    134                     num=(c[0]-'0')*100+(c[1]-'0')*10+c[2]-'0';
    135                     colcnt++;
    136                     mp[i][j].cid=colcnt;
    137                     mp[i][j].sumc=num;
    138                 }
    139                 if(c[4]!='X'){
    140                     num=(c[4]-'0')*100+(c[5]-'0')*10+c[6]-'0';
    141                     rowcnt++;
    142                     mp[i][j].rid=rowcnt;
    143                     mp[i][j].sumr=num;
    144                 }
    145             }
    146         }
    147         s=0;t=white+rowcnt+colcnt+1;
    148         tot=t+1;
    149         //编点,white<colcnt<rowcnt
    150         for(int i=0;i<n;i++)
    151         for(int j=0;j<m;j++){
    152             if(mp[i][j].type==1){
    153                 if(mp[i][j].sumc>0){ //如果列有数字
    154                     int id=mp[i][j].cid+white;
    155                     for(int k=i+1;k<n;k++){
    156                         if(mp[k][j].type==2){
    157                             add(id,mp[k][j].id,8);
    158                             mp[i][j].sumc--;
    159                         }
    160                         else break;
    161                     }
    162                     add(s,id,mp[i][j].sumc);
    163                 }
    164                 if(mp[i][j].sumr>0){
    165                     int id=mp[i][j].rid+white+colcnt;
    166                     for(int k=j+1;k<m;k++){
    167                         if(mp[i][k].type==2){
    168                             ans[i][k]=cnt;
    169                             add(mp[i][k].id,id,8);
    170                             mp[i][j].sumr--;
    171                         }
    172                         else break;
    173                     }
    174                     add(id,t,mp[i][j].sumr);
    175                 }
    176             }
    177         }
    178         int temp=ISAP();
    179        // cout<<temp<<endl;
    180         for(int i=0;i<n;i++){
    181             for(int j=0;j<m;j++){
    182                 if(mp[i][j].type==2){
    183                     printf("%d%c",e[ans[i][j]].flow+1,j==m-1?'
    ':' ');
    184                 }
    185                 else printf("_%c",j==m-1?'
    ':' ');
    186             }
    187         }
    188     }
    189     return 0;
    190 }
    TLE

     终于过了,,初始化坑死人啊。。。。

    记不清被初始化坑多少次了=_=||

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int inf=0x3f3f3f3f;
      4 const int maxv=200010;
      5 const int maxe=1000010;  //
      6 #define CLR(m,a) memset(m,a,sizeof(m))
      7 
      8 int n,m,s,t;
      9 int tot;
     10 struct Edge{
     11     int u,v,cap,flow;
     12     int nex;
     13 }e[maxe];
     14 int head[maxv];
     15 int cnt=0;
     16 void init(){
     17     CLR(head,-1);
     18     cnt=0;
     19 }
     20 void add(int u,int v,int cap)
     21 {
     22     e[cnt].u=u; e[cnt].v=v;
     23     e[cnt].cap=cap; e[cnt].flow=0;
     24     e[cnt].nex=head[u]; head[u]=cnt++;
     25 
     26     e[cnt].u=v; e[cnt].v=u;
     27     e[cnt].cap=0; e[cnt].flow=0;
     28     e[cnt].nex=head[v]; head[v]=cnt++;
     29 }
     30 struct node{
     31     int id,cid,rid,sumc,sumr,type;
     32 }mp[110][110];
     33 int ans[110][110]; //记录该点的出边,便于输出
     34 
     35 int vis[maxv],cur[maxv],num[maxv],d[maxv],p[maxv];
     36 
     37 void bfs(){
     38     CLR(d,-1);
     39     CLR(vis,0);
     40     queue<int> q;
     41     q.push(t);
     42     d[t]=0;
     43     vis[t]=1;
     44     while(!q.empty()){
     45         int u=q.front();
     46         q.pop();
     47         for(int i=head[u];~i;i=e[i].nex){
     48             int id=i&(-2);
     49             int v=e[id].u;
     50             if(!vis[v]&&e[id].cap>e[id].flow){
     51                 vis[v]=1;
     52                 q.push(v);
     53                 d[v]=d[u]+1;
     54             }
     55         }
     56     }
     57 }
     58 int augment(){
     59     int a=inf,u=t;
     60     while(u!=s){
     61         int id=p[u];
     62         a=min(a,e[id].cap-e[id].flow);
     63         u=e[id].u;
     64     }
     65     u=t;
     66     while(u!=s){
     67         int id=p[u];
     68         e[id].flow+=a;
     69         e[id^1].flow-=a;
     70         u=e[id].u;
     71     }
     72     return a;
     73 }
     74 int ISAP(){
     75     bfs();
     76     int flow=0;
     77     CLR(num,0);
     78     for(int i=0;i<tot;i++){
     79         if(d[i]!=-1) num[d[i]]++;
     80         cur[i]=head[i];
     81     }
     82     int u=s;
     83     while(d[s]<tot)
     84     {
     85         if(u==t)
     86         {
     87             flow+=augment();
     88             u=s;
     89         }
     90         int ok=0;
     91         for(int i=cur[u];~i;i=e[i].nex){
     92             int v=e[i].v;
     93             if(e[i].cap>e[i].flow&&d[u]==d[v]+1){
     94                 ok=1;
     95                 cur[u]=i;
     96                 p[v]=i;
     97                 u=v;
     98                 break;
     99             }
    100         }
    101         if(!ok){
    102             int m=tot-1;
    103             for(int i=head[u];~i;i=e[i].nex){
    104                 int v=e[i].v;
    105                 if(e[i].cap>e[i].flow&&d[v]!=-1) m=min(m,d[v]);
    106             }
    107             if(--num[d[u]]==0) break;
    108             num[d[u]=m+1]++;
    109             cur[u]=head[u];
    110             if(u!=s) u=e[p[u]].u;
    111         }
    112     }
    113     return flow;
    114 }
    115 
    116 int main(){
    117     while(scanf("%d%d",&n,&m)==2){
    118         init();
    119         char c[8];
    120         int rowcnt=0,colcnt=0,white=0;
    121         for(int i=0;i<n;i++)
    122         for(int j=0;j<m;j++){
    123             scanf("%s",c);
    124             if(c[3]=='X') {
    125                 mp[i][j].type=0;
    126                 continue;
    127             }
    128             else if(c[3]=='.'){
    129                 white++;
    130                 mp[i][j].type=2;
    131                 mp[i][j].id=white;
    132             }
    133             else{
    134                 mp[i][j].type=1;
    135                  mp[i][j].sumc=0;
    136                   mp[i][j].sumr=0;
    137                 int num;
    138                 if(c[0]!='X'){
    139                     num=(c[0]-'0')*100+(c[1]-'0')*10+c[2]-'0';
    140                     colcnt++;
    141                     mp[i][j].cid=colcnt;
    142                     mp[i][j].sumc=num;
    143                 }
    144                 if(c[4]!='X'){
    145                     num=(c[4]-'0')*100+(c[5]-'0')*10+c[6]-'0';
    146                     rowcnt++;
    147                     mp[i][j].rid=rowcnt;
    148                     mp[i][j].sumr=num;
    149                 }
    150             }
    151         }
    152         s=0;t=white+rowcnt+colcnt+1;
    153         tot=t+1;
    154         //编点,white<colcnt<rowcnt
    155         for(int i=0;i<n;i++)
    156         for(int j=0;j<m;j++){
    157             if(mp[i][j].type==1){
    158                 if(mp[i][j].sumc>0){ //如果列有数字
    159                     int id=mp[i][j].cid+white;
    160                     for(int k=i+1;k<n;k++){
    161                         if(mp[k][j].type==2){
    162                             add(id,mp[k][j].id,8);
    163                             mp[i][j].sumc--;
    164                         }
    165                         else break;
    166                     }
    167                     add(s,id,mp[i][j].sumc);
    168                 }
    169                 if(mp[i][j].sumr>0){
    170                     int id=mp[i][j].rid+white+colcnt;
    171                     for(int k=j+1;k<m;k++){
    172                         if(mp[i][k].type==2){
    173                             ans[i][k]=cnt;
    174                             add(mp[i][k].id,id,8);
    175                             mp[i][j].sumr--;
    176                         }
    177                         else break;
    178                     }
    179                     add(id,t,mp[i][j].sumr);
    180                 }
    181             }
    182         }
    183         int temp=ISAP();
    184         for(int i=0;i<n;i++){
    185             for(int j=0;j<m;j++){
    186                 if(mp[i][j].type==2){
    187                     printf("%d%c",e[ans[i][j]].flow+1,j==m-1?'
    ':' ');
    188                 }
    189                 else printf("_%c",j==m-1?'
    ':' ');
    190             }
    191         }
    192     }
    193     return 0;
    194 }
    View Code

    kebab

     HDU - 2883 

    题意:n个任务,每个任务时间区间为[si,ei],工作量为ni*ti。单位时间最大工作量为m,求是否能完成任务。

    和上面的hdu3572类似,区别就是这个工作可以分成ni份同时做,还有这个题的时间区间较大,先离散化,再把每个区间看成一个点。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define CLR(m,a) memset(m,a,sizeof(m))
      4 const int maxv=610;
      5 const int maxe=100010;
      6 const int inf=0x3f3f3f3f;
      7 struct Edge{
      8     int u,v,flow,cap;
      9     int nex;
     10     Edge(int u=0,int v=0,int flow=0,int cap=0,int nex=0):
     11         u(u),v(v),flow(flow),cap(cap),nex(nex){}
     12 }e[maxe<<2];
     13 int head[maxv];
     14 int cnt=0;
     15 void init(){
     16     CLR(head,-1);
     17     cnt=0;
     18 }
     19 void add(int u,int v,int cap){
     20     e[cnt]=Edge(u,v,0,cap,head[u]);
     21     head[u]=cnt++;
     22     e[cnt]=Edge(v,u,0,0,head[v]);
     23     head[v]=cnt++;
     24 }
     25 int si[maxv],ei[maxv],ti[maxv],ni[maxv];
     26 int des[maxv<<1];
     27 
     28 int d[maxv],num[maxv],cur[maxv],p[maxv];
     29 int vis[maxv];
     30 int s,t;
     31 int N;  //
     32 
     33 void bfs(){
     34     CLR(d,-1);
     35     CLR(vis,0);
     36     queue<int> q;
     37     q.push(t);
     38     d[t]=0;
     39     vis[t]=1;
     40     while(!q.empty()){
     41         int u=q.front();
     42         q.pop();
     43         for(int i=head[u];~i;i=e[i].nex){
     44             int id=i&(-2);
     45             int v=e[id].u;
     46             if(!vis[v]&&e[id].cap>e[id].flow){
     47                 vis[v]=1;
     48                 d[v]=d[u]+1;
     49                 q.push(v);
     50             }
     51         }
     52     }
     53     //
     54 }
     55 
     56 int augment(){
     57     int u=t,a=inf;
     58     while(u!=s){
     59         int id=p[u];
     60         a=min(a,e[id].cap-e[id].flow);
     61         u=e[id].u;
     62     }
     63     u=t;
     64     while(u!=s){
     65         int id=p[u];
     66         e[id].flow+=a;
     67         e[id^1].flow-=a;
     68         u=e[id].u;
     69     }
     70     return a;
     71 }
     72 
     73 int ISAP(){
     74     bfs();
     75     int flow=0;
     76     CLR(num,0);
     77     for(int i=0;i<N;i++){
     78         cur[i]=head[i];
     79         if(~d[i]) num[d[i]]++;
     80     }
     81     int u=s;
     82     while(d[s]<N){
     83         if(u==t){
     84             flow+=augment();
     85             u=s;
     86         }
     87         int ok=0;
     88         for(int i=cur[u];~i;i=e[i].nex){
     89             int v=e[i].v;
     90             if(d[u]==d[v]+1&&e[i].cap>e[i].flow){
     91                 p[v]=i;
     92                 ok=1;
     93                 cur[u]=i;
     94                 u=v;
     95                 break;
     96             }
     97         }
     98         if(!ok){
     99             int m=N-1;
    100             for(int i=head[u];~i;i=e[i].nex){
    101                 if(e[i].cap>e[i].flow&&~d[e[i].v]) m=min(m,d[e[i].v]);
    102             }
    103             if(--num[d[u]]==0) break;
    104             num[d[u]=m+1]++;
    105             cur[u]=head[u];
    106             if(u!=s) u=e[p[u]].u;
    107         }
    108     }
    109     return flow;
    110 }
    111 
    112 int main(){
    113     int n,m;
    114     while(scanf("%d%d",&n,&m)!=EOF){
    115         int sum=0;
    116         int p=0;
    117         init();
    118         for(int i=1;i<=n;i++){
    119             scanf("%d%d%d%d",&si[i],&ni[i],&ei[i],&ti[i]);
    120             des[p++]=si[i];
    121             des[p++]=ei[i];
    122             sum+=ni[i]*ti[i];
    123         }
    124         sort(des,des+p);
    125         p=unique(des,des+p)-des;
    126         s=0,t=n+p;
    127         for(int i=1;i<=n;i++){
    128             add(s,i,ti[i]*ni[i]);
    129         }
    130         for(int i=1;i<p;i++){
    131             add(n+i,t,(des[i]-des[i-1])*m);
    132             for(int j=1;j<=n;j++){
    133                 if(si[j]<=des[i-1]&&ei[j]>=des[i])
    134                     add(j,n+i,inf);
    135             }
    136         }
    137         N=t+1;
    138         int flow=ISAP();
    139         if(flow==sum) puts("Yes");
    140         else puts("No");
    141     }
    142 }
    View Code

    Escape

     HDU - 3605 

    题意:n个人移民到m个星球。问是否能满足所有人的需求(即有的人不去某些星球)。

    n有十万,m最大10,开始直接上模板做的,果断TLE,边数达到了1e6+。

    注意到m最大是10,与n差距悬殊。考虑有多少种移民方案,每个星球选或者不选,所以最多1024种

    以方案为点,该方案允许的人为边,再去建图

    这样建图边数降到了1e4,过了~

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define CLR(m,a) memset(m,a,sizeof(m))
      4 const int maxv=1050;
      5 const int maxe=12000;
      6 const int inf=0x3f3f3f3f;
      7 struct Edge{
      8     int u,v,flow,cap;
      9     int nex;
     10     Edge(int u=0,int v=0,int flow=0,int cap=0,int nex=0):
     11         u(u),v(v),flow(flow),cap(cap),nex(nex){}
     12 }e[maxe<<1];
     13 int head[maxv];
     14 int cnt=0;
     15 void init(){
     16     CLR(head,-1);
     17     cnt=0;
     18 }
     19 void add(int u,int v,int cap){
     20     e[cnt]=Edge(u,v,0,cap,head[u]);
     21     head[u]=cnt++;
     22     e[cnt]=Edge(v,u,0,0,head[v]);
     23     head[v]=cnt++;
     24 }
     25 int vis[maxv],p[maxv],d[maxv],num[maxv],cur[maxv];
     26 int s,t;
     27 int N;
     28 
     29 void bfs(){
     30     CLR(d,-1);
     31     CLR(vis,0);
     32     queue<int> q;
     33     q.push(t);
     34     d[t]=0;
     35     vis[t]=1;
     36     while(!q.empty()){
     37         int u=q.front();
     38         q.pop();
     39         for(int i=head[u];~i;i=e[i].nex){
     40             int id=i&(-2);
     41             int v=e[id].u;
     42             if(!vis[v]&&e[id].cap>e[id].flow){
     43                 vis[v]=1;
     44                 d[v]=d[u]+1;
     45                 q.push(v);
     46             }
     47         }
     48     }
     49 }
     50 int augment(){
     51     int u=t,a=inf;
     52     while(u!=s){
     53         int id=p[u];
     54         a=min(a,e[id].cap-e[id].flow);
     55         u=e[id].u;
     56     }
     57     u=t;
     58     while(u!=s){
     59         int id=p[u];
     60         e[id].flow+=a;
     61         e[id^1].flow-=a;
     62         u=e[id].u;
     63     }
     64     return a;
     65 }
     66 int ISAP(){
     67     bfs();
     68     CLR(num,0);
     69     for(int i=0;i<N;i++){
     70         cur[i]=head[i];
     71         if(~d[i]) num[d[i]]++;
     72     }
     73     int flow=0;
     74     int u=s;
     75     while(d[s]<N){
     76         if(u==t){
     77             flow+=augment();
     78             u=s;
     79         }
     80         int ok=0;
     81         for(int i=cur[u];~i;i=e[i].nex){
     82             int v=e[i].v;
     83             if(d[u]==d[v]+1&&e[i].cap>e[i].flow){
     84                 ok=1;
     85                 p[v]=i;
     86                 cur[u]=i;
     87                 u=v;
     88                 break;
     89             }
     90         }
     91         if(!ok){
     92             int m=N-1;
     93             for(int i=head[u];~i;i=e[i].nex){
     94                 if(e[i].cap>e[i].flow&&~d[e[i].v]) m=min(m,d[e[i].v]);
     95             }
     96             if(--num[d[u]]==0) break;
     97             num[d[u]=m+1]++;
     98             cur[u]=head[u];
     99             if(u!=s) u=e[p[u]].u;
    100         }
    101     }
    102     return flow;
    103 }
    104 int val[maxv];
    105 int main(){
    106     int n,m;
    107     while(scanf("%d%d",&n,&m)!=EOF){
    108         init();
    109         int x;
    110         CLR(val,0);
    111         for(int i=1;i<=n;i++){
    112             int temp=0;
    113             for(int j=1;j<=m;j++){
    114                 scanf("%d",&x);
    115                 temp=(temp<<1)+x;
    116             }
    117             val[temp]++;
    118         }
    119         int bc=(1<<m)-1;
    120         s=0;t=bc+m+1;
    121         N=t+1;
    122         for(int i=1;i<=m;i++){
    123             scanf("%d",&x);
    124             add(bc+i,t,x);
    125         }
    126         if(val[0]) {
    127             puts("NO");
    128             continue;
    129         }
    130         for(int i=1;i<=bc;i++)if(val[i]){
    131             add(s,i,val[i]);
    132              for(int j=1;j<=m;j++) if(i>>(m-j)&1){  //位运算又出了差错=_=|| 
    133                 add(i,bc+j,inf);
    134             }
    135         }
    136         int flow=ISAP();
    137         if(flow==n) puts("YES");
    138         else puts("NO");
    139     }
    140     return 0;
    141 }
    View Code
  • 相关阅读:
    电磁学讲义3:电场
    电磁学讲义2:库仑定律
    电磁学讲义1:静电的基本现象
    安卓(Android)手机如何安装APK?
    理论物理极础9:相空间流体和吉布斯-刘维尔定理
    物理学家的LOGO
    Zhulina 的高分子刷理论
    一步一步学Silverlight 2系列(5):实现简单的拖放功能
    地图上显示X,Y 坐标代码
    一步一步学Silverlight 2系列(4):鼠标事件处理
  • 原文地址:https://www.cnblogs.com/yijiull/p/7231275.html
Copyright © 2020-2023  润新知