zoukankan      html  css  js  c++  java
  • HDU

    思路:tarjarn缩点,然后剩下的就是纯粹的最小路径覆盖,最小路径覆盖=顶点数-匹配数。匹配数跑一遍匈牙利即可。

      1 #include <iostream>
      2 #include <queue>
      3 #include <stack>
      4 #include <cstdio>
      5 #include <vector>
      6 #include <map>
      7 #include <set>
      8 #include <bitset>
      9 #include <algorithm>
     10 #include <cmath>
     11 #include <cstring>
     12 #include <cstdlib>
     13 #include <string>
     14 #include <sstream>
     15 #include <time.h>
     16 #define x first
     17 #define y second
     18 #define pb push_back
     19 #define mp make_pair
     20 #define lson l,m,rt*2
     21 #define rson m+1,r,rt*2+1
     22 #define mt(A,B) memset(A,B,sizeof(A))
     23 using namespace std;
     24 typedef long long LL;
     25 //const double PI = acos(-1);
     26 const int N=5e5+10;
     27 const LL mod=1e9+7;
     28 const int inf = 0x3f3f3f3f;
     29 const LL INF=0x3f3f3f3f3f3f3f3fLL;
     30 const int MAXN = 5010;//点数
     31 const int MAXM = 200010;//边数
     32 struct Edge
     33 {
     34     int to,next;
     35 } edge[MAXM],edge1[MAXM];
     36 int head[MAXN],tot;
     37 int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~scc
     38 int Index,top;
     39 int scc;//强连通分量的个数
     40 bool Instack[MAXN];
     41 int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc
     42 //num数组不一定需要,结合实际情况
     43 void addedge(int u,int v)
     44 {
     45     edge[tot].to = v;
     46     edge[tot].next = head[u];
     47     head[u] = tot++;
     48 }
     49 void Tarjan(int u)
     50 {
     51     int v;
     52     Low[u] = DFN[u] = ++Index;
     53     Stack[top++] = u;
     54     Instack[u] = true;
     55     for(int i = head[u]; i != -1; i = edge[i].next)
     56     {
     57         v = edge[i].to;
     58         if( !DFN[v] )
     59         {
     60             Tarjan(v);
     61             if( Low[u] > Low[v] )Low[u] = Low[v];
     62         }
     63         else if(Instack[v] && Low[u] > DFN[v])
     64             Low[u] = DFN[v];
     65     }
     66     if(Low[u] == DFN[u])
     67     {
     68         scc++;
     69         do
     70         {
     71             v = Stack[--top];
     72             Instack[v] = false;
     73             Belong[v] = scc;
     74             num[scc]++;
     75         }
     76         while( v != u);
     77     }
     78 }
     79 void solve(int N)
     80 {
     81     memset(DFN,0,sizeof(DFN));
     82     memset(Instack,false,sizeof(Instack));
     83     memset(num,0,sizeof(num));
     84     Index = scc = top = 0;
     85     for(int i = 1; i <= N; i++)
     86         if(!DFN[i])
     87             Tarjan(i);
     88 }
     89 int head1[MAXN],tot1;
     90 void init()
     91 {
     92     tot = 0;
     93     tot1 = 0;
     94     memset(head,-1,sizeof(head));
     95     memset(head1,-1,sizeof(head1));
     96 }
     97 void addedge1(int u,int v)
     98 {
     99     edge1[tot1].to = v;
    100     edge1[tot1].next = head1[u];
    101     head1[u] = tot1++;
    102 }
    103 int linker[MAXN];
    104 bool used[MAXN];
    105 bool dfs(int u)
    106 {
    107     for(int i = head1[u]; i != -1 ; i = edge1[i].next)
    108     {
    109         int v = edge1[i].to;
    110         if(!used[v])
    111         {
    112             used[v] = true;
    113             if(linker[v] == -1 || dfs(linker[v]))
    114             {
    115                 linker[v] = u;
    116                 return true;
    117             }
    118         }
    119     }
    120     return false;
    121 }
    122 int hungary(int uN)
    123 {
    124     int res = 0;
    125     memset(linker,-1,sizeof(linker));
    126     for(int u = 1; u <=uN; u++)
    127     {
    128         mt(used,0);
    129         if(dfs(u))
    130         {
    131             res++;
    132         }
    133     }
    134     return res;
    135 }
    136 int main()
    137 {
    138 #ifdef Local
    139     freopen("data.txt","r",stdin);
    140 #endif
    141     ios::sync_with_stdio(false);
    142     cin.tie(0);
    143     int T;
    144     int n,m,u,v;
    145     cin>>T;
    146     while(T--)
    147     {
    148         cin>>n>>m;
    149         init();
    150         for(int i=0; i<m; i++)
    151         {
    152             cin>>u>>v;
    153             addedge(u,v);
    154         }
    155         solve(n);
    156         for(int i=1; i<=n; i++)
    157         {
    158             for(int j=head[i]; ~j; j=edge[j].next) //j表示读入的是第几条边
    159             {
    160                 if(Belong[i]!=Belong[edge[j].to])
    161                 {
    162                    addedge1(Belong[i],Belong[edge[j].to]);
    163                    //cout<<Belong[i]<<"->"<<Belong[edge[j].to]<<endl;
    164                 }
    165             }
    166         }
    167         //cout<<hungary(scc)<<endl;
    168         cout<<scc-hungary(scc)<<endl;
    169     }
    170 #ifdef Local
    171     cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    172 #endif
    173 }
    View Code
  • 相关阅读:
    CF1172F
    CF506E
    【清华集训2014】玛里苟斯
    CF516E Drazil and His Happy Friends
    [NOI2017]游戏(2-SAT)
    [bzoj2878][Noi2012]迷失游乐园(基环树dp)
    bzoj3545/bzoj3551 [ONTAK2010]Peaks/Peaks加强版
    [bzoj1791][ioi2008]Island 岛屿(基环树、树的直径)
    [AT2306]Rearranging(拓扑序)
    [bzoj5301][Cqoi2018]异或序列
  • 原文地址:https://www.cnblogs.com/27sx/p/6696925.html
Copyright © 2011-2022 走看看