UVA - 11838 Come and Go && UVA - 11770 Lighting Away (强连通分量)

来源:互联网 发布:js ajax 跨域 编辑:程序博客网 时间:2024/06/06 20:00
链接 :


http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27318

链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20874


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;}



2 1