• SGU 242 Student's Morning (网络流+打印路径,Dinic)


    http://acm.sgu.ru/problem.php?contest=0&problem=242

    网络流+打印路径

    原点和人建立权为1的边,人和学校建立权为1的边,学校和汇点建权为2的边

    最大流是2*k则yes,否则no

    顺便附上修改自他人的带各种优化的Dinic模板~

      1 /**
      2 *网络流+打印路径
      3 *原点和人建立权为1的边,学校和汇点建权为2的边
      4 *最大流是2*k则yes,否则no
      5 *
      6 *@Author: xysmlx xiaohai
      7 */
      8 //#pragma comment(linker, "/STACK:102400000,102400000")
      9 #include<cstdio>
     10 #include<iostream>
     11 #include<cstring>
     12 #include<string>
     13 #include<cmath>
     14 #include<set>
     15 #include<list>
     16 #include<map>
     17 #include<iterator>
     18 #include<cstdlib>
     19 #include<vector>
     20 #include<queue>
     21 #include<stack>
     22 #include<algorithm>
     23 #include<functional>
     24 using namespace std;
     25 typedef long long LL;
     26 #define ROUND(x) round(x)
     27 #define FLOOR(x) floor(x)
     28 #define CEIL(x) ceil(x)
     29 const int maxn=510;
     30 const int inf=0x3f3f3f3f;
     31 const LL inf64=0x3f3f3f3f3f3f3f3fLL;
     32 const double INF=1e30;
     33 const double eps=1e-6;
     34 
     35 /**
     36 *最大流:加各种优化的Dinic算法($O(V^2E)$)
     37 *输入:图(链式前向星),n(顶点个数,包含源汇),st(源),ed(汇)
     38 *输出:MaxFlow()(最大流)
     39 */
     40 //const int maxn=0;
     41 const int maxm=50010;
     42 //const int inf=0x3f3f3f3f;
     43 struct Edge
     44 {
     45     int v;
     46     int cap;
     47     int next;
     48 } edge[maxm];
     49 int head[maxn],edgeNum;//需初始化
     50 int n,m,d[maxn],cur[maxn];
     51 int st,ed;
     52 void addSubEdge(int u,int v,int cap)
     53 {
     54     edge[edgeNum].v=v;
     55     edge[edgeNum].cap=cap;
     56     edge[edgeNum].next=head[u];
     57     head[u]=edgeNum++;
     58     cur[u]=head[u];
     59 }
     60 void addEdge(int u,int v,int cap)
     61 {
     62     addSubEdge(u,v,cap);
     63     addSubEdge(v,u,0);//注意加反向0边
     64 }
     65 bool BFS()
     66 {
     67     queue<int> Q;
     68     memset(d, -1, sizeof(d));
     69     Q.push(st);
     70     d[st]=0;
     71     while (!Q.empty())
     72     {
     73         int u=Q.front();
     74         Q.pop();
     75         for(int i=head[u]; i!=-1; i=edge[i].next)
     76         {
     77             int v=edge[i].v;
     78             int cap=edge[i].cap;
     79             if(cap&&d[v]==-1)
     80             {
     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 cap=edge[i].cap;
     97         if (cap && d[v]==d[u]+1)
     98         {
     99             delta = Aug(v, min(a,cap));
    100             if (delta)
    101             {
    102                 edge[i].cap -= delta;
    103                 edge[i^1].cap += delta;
    104                 aug += delta;
    105                 if (!(a-=delta)) break;
    106             }
    107         }
    108     }
    109     if (!aug) d[u]=-1;
    110     return aug;
    111 }
    112 int MaxFlow()
    113 {
    114     int flow=0;
    115     while (BFS())
    116     {
    117         memcpy(cur,head,sizeof(int)*(n+1));
    118         flow += Aug(st,inf);
    119     }
    120     return flow;
    121 }
    122 
    123 int N,M;
    124 void init()
    125 {
    126     memset(head,-1,sizeof(head));
    127     edgeNum=0;
    128     st=0,ed=N+M+1;
    129     n=N+M+1;
    130 }
    131 void input()
    132 {
    133     for(int i=1;i<=N;i++)
    134     {
    135         addEdge(st,i,1);
    136         int u,v;
    137         scanf("%d",&u);
    138         for(int j=0;j<u;j++)
    139         {
    140             scanf("%d",&v);
    141             addEdge(i,N+v,1);
    142         }
    143     }
    144     for(int i=1;i<=M;i++) addEdge(N+i,ed,2);
    145 }
    146 void solve()
    147 {
    148     int f=MaxFlow();
    149     if(f!=2*M)
    150     {
    151         puts("NO");
    152         return;
    153     }
    154     puts("YES");
    155     for(int v=1;v<=M;v++)
    156     {
    157         printf("2");
    158         for(int i=head[N+v];i!=-1;i=edge[i].next)
    159         {
    160             if((i&1)&&edge[i].cap==1) printf(" %d",edge[i].v);
    161         }
    162         puts("");
    163     }
    164 }
    165 int main()
    166 {
    167 //    std::ios_base::sync_with_stdio(false);
    168 //    freopen("in.cpp","r",stdin);
    169     while(~scanf("%d%d",&N,&M))
    170     {
    171         init();
    172         input();
    173         solve();
    174     }
    175     return 0;
    176 }
    View Code
  • 相关阅读:
    8.16集训
    8.15集训
    Educational Codeforces Round 97 (Rated for Div. 2)
    Codeforces Round #679 (Div. 2, based on Technocup 2021 Elimination Round 1)
    尺取法
    Codeforces Round #677 (Div. 3)
    单调队列
    dfs序
    离散化
    [kuangbin带你飞]专题七 线段树
  • 原文地址:https://www.cnblogs.com/xysmlx/p/3288113.html
Copyright © 2020-2023  润新知