1. 程式人生 > >11838 Come and Go && UVA

11838 Come and Go && UVA

連結 : 

11838 :求一張圖可否任意兩點可達 。直接判斷整個圖是否強連通。

#pragma comment(linker, "/STACK:10240000,10240000")
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#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 = 2005;
const int M = 20005;
typedef long long ll;
using namespace std;

int n, m;
vector <int> G[N];
int pre[N], low[N], scc[N], dfs_clock, scc_cnt;
stack <int> S;
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], pre[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);

    while(cin >> n >> m && n + m) {

        for(int i = 0; i < n; i++) G[i].clear();

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

        find_scc();

        int ans = 1;
        if(scc_cnt == 1) {
            ans = 1;
        } else ans = 0;

        printf("%d\n", ans);
    }

    return 0;
}

11770 :與11504多米諾骨牌幾乎為同一題。強連通縮點後找出所有入度為0的點。

#pragma comment(linker, "/STACK:10240000,10240000")
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#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 = 10005;
const int M = 20005;
typedef long long ll;
using namespace std;

int n, m;
vector <int> G[N];
int pre[N], low[N], scc[N], dfs_clock, scc_cnt;
stack <int> S;
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], pre[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);

    int T, ca = 1;
    cin >> T;
    while(T--) {

        for(int i = 0; i < n; i++) G[i].clear();
        cin >> n >> m;
        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[u] != scc[v]) {
                    vis[ scc[v] ]++;
                }
            }
        }

        int cnt = 0;
        for(int i = 1; i <= scc_cnt; i++) {
            if(vis[i] == 0) cnt++;
        }

        printf("Case %d: %d\n", ca++, cnt);


    }

    return 0;
}