zoukankan      html  css  js  c++  java
  • [HihoCoder1394]网络流四·最小路径覆盖

    题目大意:
    从有向无环图中选出若干点不想交的链,使得这些链覆盖所有的点,并且链的条数最小。

    思路:
    设超级源点$S$、超级汇点$T$。
    将$N$个点复制一份,分为$A$部和$B$部。
    对于$A$部的所有点$A_i$,连一条从$S$到$A_i$的边;
    对于$B$部的所有点$B_i$,连一条从$B_i$到$T$的边。
    用最大流跑一边二分图匹配,得到的最大流F为每条链上入度为0的点的个数总和,而B部中未被匹配的点对应着每个链的头。
    答案即为N-F。

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<vector>
     5 #include<cstring>
     6 inline int getint() {
     7     char ch;
     8     while(!isdigit(ch=getchar()));
     9     int x=ch^'0';
    10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    11     return x;
    12 }
    13 int s,t;
    14 const int E=42000,V=1002;
    15 struct Edge {
    16     int from,to;
    17     bool remain;
    18 };
    19 Edge e[E];
    20 std::vector<int> g[V];
    21 int sz=0;
    22 inline void add_edge(const int u,const int v,const bool w) {
    23     e[sz]=(Edge){u,v,w};
    24     g[u].push_back(sz);
    25     sz++;
    26 }
    27 int p[V];
    28 bool a[V];
    29 inline bool Augment() {
    30     memset(a,0,sizeof a);
    31     a[s]=true;
    32     std::queue<int> q;
    33     q.push(s);
    34     while(!q.empty()&&!a[t]) {
    35         int x=q.front();
    36         q.pop();
    37         for(unsigned i=0;i<g[x].size();i++) {
    38             Edge &y=e[g[x][i]];
    39             if(!a[y.to]&&y.remain) {
    40                 p[y.to]=g[x][i];
    41                 a[y.to]=a[x]&&y.remain;
    42                 q.push(y.to);
    43             }
    44         }
    45     }
    46     return a[t];
    47 }
    48 inline int EdmondsKarp() {
    49     int maxflow=0;
    50     while(Augment()) {
    51         for(int i=t;i!=s;i=e[p[i]].from) {
    52             e[p[i]].remain^=true;
    53             e[p[i]^1].remain^=true;
    54         }
    55         maxflow++;
    56     }
    57     return maxflow;
    58 }
    59 int main() {
    60     int n=getint(),m=getint();
    61     s=0,t=n<<1|1;
    62     for(int i=1;i<=n;i++) {
    63         add_edge(s,i,true);
    64         add_edge(i,s,false);
    65         add_edge(n+i,t,true);
    66         add_edge(t,n+i,false);
    67     }
    68     for(int i=1;i<=m;i++) {
    69         int u=getint(),v=getint();
    70         add_edge(u,n+v,true);
    71         add_edge(n+v,u,false);
    72     }
    73     printf("%d
    ",n-EdmondsKarp());
    74     return 0;
    75 }
  • 相关阅读:
    POJ 3710 Christmas Game#经典图SG博弈
    POJ 2599 A funny game#树形SG(DFS实现)
    POJ 2425 A Chess Game#树形SG
    LeetCode Array Easy 122. Best Time to Buy and Sell Stock II
    LeetCode Array Easy121. Best Time to Buy and Sell Stock
    LeetCode Array Easy 119. Pascal's Triangle II
    LeetCode Array Easy 118. Pascal's Triangle
    LeetCode Array Easy 88. Merge Sorted Array
    ASP.NET MVC 学习笔记之 MVC + EF中的EO DTO ViewModel
    ASP.NET MVC 学习笔记之面向切面编程与过滤器
  • 原文地址:https://www.cnblogs.com/skylee03/p/7252104.html
Copyright © 2011-2022 走看看