程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> UVA - 11504 Dominos 強連通分量

UVA - 11504 Dominos 強連通分量

編輯:C++入門知識

UVA - 11504 Dominos 強連通分量


 

 

題意 :多米諾骨牌 如果有邊存在u -> v 說明u倒了v也自動倒了。問最少需要手動推到幾個。

如果一些牌屬於同一個強連通分量 那麼任意推倒其中之一就算全部推倒。可以強連通縮點之後 推倒的一定是沒有入度的牌。

 

注意 這題不能直接判斷所有入度為0的點有幾個,因為可能存在入度都不為0 但是存在多個強連通分量。比如

n = 6, m = 6

1 -> 2,

2 -> 3,

3 -> 1,

4 -> 5,

5 -> 6,

6 -> 4.

雖然沒有入度為0的點 但是需要推2次。

 

 

#pragma comment(linker, /STACK:10240000,10240000)
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include
#define mod 4294967296
#define MAX 0x3f3f3f3f
#define lson o<<1, l, m
#define rson o<<1|1, m+1, r
#define SZ(x) ((int)ans.size())
#define MAKE make_pair
#define INFL 0x3f3f3f3f3f3f3f3fLL
#define mem(a) memset(a, 0, sizeof(a))
const double pi = acos(-1.0);
const double eps = 1e-9;
const int N = 100005;
const int M = 20005;
typedef long long ll;
using namespace std;

int n, m;
vector  G[N];
int pre[N], low[N], scc[N], dfs_clock, scc_cnt;
stack  S;
int T;
void dfs(int u) {
    pre[u] = low[u] = ++dfs_clock;
    S.push(u);
    for(int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if(pre[v] == 0) {
            dfs(v);
            low[u] = min(low[u], low[v]);
        } else if(scc[v] == 0) {
            low[u] = min(low[u], low[v]);
        }
    }
    if(low[u] == pre[u]) {
        scc_cnt++;
        for(;;) {
            int x = S.top(); S.pop();
            scc[x] = scc_cnt;
            if(x == u) break;
        }
    }
}
void find_scc() {
    dfs_clock = scc_cnt = 0;
    mem(scc);
    mem(pre);
    for(int i = 0; i < n; i++) {
        if(pre[i] == 0) dfs(i);
    }
}
int vis[N];
int main()  {

    //freopen(in.txt,r,stdin);
    cin >> T;
    while(T--) {
        cin >> n >> m;

        for(int i = 0; i < n; i++) G[i].clear();
        for(int i = 0; i < m; i++) {
            int x, y;
            scanf(%d%d, &x, &y);
            x--, y--;
            G[x].push_back(y);
        }

        find_scc();

        mem(vis);
        for(int u = 0; u < n; u++) {
            for(int i = 0; i < G[u].size(); i++) {
                int v = G[u][i];
                if(scc[v] != scc[u]) {
                    vis[ scc[v] ]++;
                }
            }
        }
        int cnt = 0;
        //cout << scc_cnt << endl;
        for(int i = 1; i <= scc_cnt; i++) {
            if(vis[i] == 0) cnt++;
        }
        cout << cnt << endl;

    }


    return 0;
}

 

 

??

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved