問題の説明
この問題では、我々は、非環式有向グラフG =(V、E)の到達不能セットについてお話したいと思います。
数学では非循環有向グラフ(DAG)が無指向サイクルの有向グラフです。すなわち、任意のノードで開始し、最終的に再び開始するループEのエッジの一貫指向シーケンスを追跡する方法がないようなグラフです。
いくつかのノードを含むVUR⊂Vで表されるノードセットはそれぞれ2つの異なるノードuおよびVURにおけるVため、Uから始まり、中辺の一貫有向順序を追跡する方法がない、場合Gの到達不能なノード・セットとして知られていますE最後にアーカイブはあなたがこの問題で求められます。ノードvが与えられたグラフGの最大到達不可能なノードセットのサイズを計算すること
入力
入力は、いくつかのテストケースを含み、最初の行は、整数テストケースの数であり、T(1≤T≤500)を含みます。
各場合について、最初の行は、各ノードの数、グラフ内のエッジの数G.を示す二つの整数N(1≤N≤100)及びmは(0≤M≤N(N-1)/ 2)が含まれ次のm行の二つの整数uとvとの有向エッジ説明(1≤U、Vを≤Nおよびu̸= V)V番目のノードへのu番目のノードからエッジを示します。この場合、提供されるすべてのエッジが明瞭です。
我々は、入力で与えられた全ての有向グラフでのDAGであることを保証し、入力中のmの合計は500000未満です。
出力
各テストケースのためのGの最大到達不能なノードセットのサイズであるラインにおいて、出力整数
サンプル入力
3
4 4
1 2
1 3
2 4
3 4
4 3
1 2
2 3
3 4
5 6
1 2
4 2
6 2
2 3
2 5サンプル出力
2
1
3
問題の意味:データのTセットが、各グループは、ポイントが付与され、nおよびmは非巡回グラフを有向エッジ、図は、点集合を有する点のこの到達不能な最大数を尋ねます
アイデア:最大独立集合を、いわゆる最大到達不能設定点は、図は、最大一致のためにハンガリー推移閉包アルゴリズムを取得するために使用する前に、このように図DAG推移閉包に最初求め、DAGので、示されています最終的な答えは、点の総数マイナスマッチの最大数であります
ソースプログラム
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<unordered_map>
#include<bitset>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<int,int>
LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; }
LL multMod(LL a,LL b,LL mod){ a%=mod; b%=mod; LL res=0; while(b){if(b&1)res=(res+a)%mod; a=(a<<=1)%mod; b>>=1; } return res%mod;}
LL quickMultPowMod(LL a, LL b,LL mod){ LL res=1,k=a; while(b){if((b&1))res=multMod(res,k,mod)%mod; k=multMod(k,k,mod)%mod; b>>=1;} return res%mod;}
LL quickPowMod(LL a,LL b,LL mod){ LL res=1; while(b){if(b&1)res=(a*res)%mod; a=(a*a)%mod; b>>=1; } return res; }
LL getInv(LL a,LL mod){ return quickPowMod(a,mod-2,mod); }
LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); }
LL LCM(LL x,LL y){ return x/GCD(x,y)*y; }
const double EPS = 1E-10;
const int MOD = 1000000000+7;
const int N = 1000+5;
const int dx[] = {0,0,-1,1,1,-1,1,1};
const int dy[] = {1,-1,0,0,-1,1,-1,1};
using namespace std;
int n,m;
bool vis[N];
int link[N];
bool G[N][N];
bool dfs(int x){
for(int y=1;y<=n;y++){
if(G[x][y]&&!vis[y]){
vis[y]=true;
if(link[y]==-1 || dfs(link[y])){
link[y]=x;
return true;
}
}
}
return false;
}
int hungarian(){
int ans=0;
for(int i=1;i<=n;i++){
memset(vis,false,sizeof(vis));
if(dfs(i))
ans++;
}
return ans;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
memset(link,-1,sizeof(link));
memset(G,false,sizeof(G));
scanf("%d%d",&n,&m);
while(m--){
int x,y;
scanf("%d%d",&x,&y);
G[x][y]=true;
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
G[i][j]|=G[i][k]&G[k][j];
int mate=hungarian();
int res=n-mate;
printf("%d\n",res);
}
return 0;
}