最大到達不能ノードセット(UVALive-8456)

問題の説明

この問題では、我々は、非環式有向グラフ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;
}

 

リリース1871元の記事 ウォンの賞賛702 ビュー194万+

おすすめ

転載: blog.csdn.net/u011815404/article/details/102650553