24h購物| | PChome| 登入
2012-08-28 10:51:07| 人氣1,472| 回應0 | 上一篇 | 下一篇

[UVA][SCC、Tarjan算法] 11770 - Lighting Away

推薦 0 收藏 0 轉貼0 訂閱站台

J

Lighting Away

Input: Standard Input

Output: Standard Output

Ronju is a night-guard at the “Lavish office buildings Ltd.” headquarters. The office has a large grass field in front of the building. So every day, when Ronju comes to duty at the evening, it is his duty to turn on all the lights in the field. However, given the large size of the field and the large number of lights, it is very tiring for him to walk to each and every individual light to turn it on.

 

So he has devised an ingenious plan – he will swap the switches for light-sensitive triggers. A local electronic store nearby sells these funny trigger switches at a very cheap price. Once installed at a light-post, it will automatically turn that light on whenever it can sense some other light lighting up nearby. So from now on, Ronju can just manually flip a few switches, and the light from those will trigger nearby sensors, which will in turn light up some more lights nearby, and so on, gradually lighting up the whole field.

 

Now Ronju wonders: how many switches does he have to flip manually for this?

 

Input

The input starts with an integer T, the number of test cases to follow. Each test case will start with two integers N (1 <= N <= 10000) and M (0 <= M <= 100000), where N is the number of lights in the field, and M more lines of input follows in this input case. Each of these extra M lines will have two integers a and b separated by a space, where 1 <= a, b <= N, indicating that if the light a lights up, it will trigger the light b to turn on as well (according to their distance, brightness, sensor sensitivity, orientation and other complicated factors). Finally, every test case in the input will be followed by a blank line.

                                                                                                           

Output

For each input test case, the output must be a single line of the format “Case k: c” where k is the case number starting with 1, and c is the minimum number of lights that Ronju must turn on manually before all the lights in the whole field gets lit up.

 

Sample Input                               Output for Sample Input

2

5 4

1 2

1 3

3 4

5 3

 

4 4

1 2

1 3

4 2

4 3

 

Case 1: 2

Case 2: 2

 



做法 : 跟 11504 - Dominos 一樣, 將 SCC 縮點, 找 indeg 為 0 的個數

#include <stdio.h>
#include <vector>
#include <stack>
#include <algorithm>
#define maxN 10010
using namespace std;
vector<int> g[maxN];
int stk[maxN], stkIdx;
int visited[maxN], in_stk[maxN];
int vfind[maxN], findIdx;
int lead[maxN];
int scc(int nd) {
    visited[nd] = in_stk[nd] = 1;
    stk[++stkIdx] = nd;
    vfind[nd] = ++findIdx;
    int mn = vfind[nd];
    for(vector<int>::iterator it = g[nd].begin();
        it != g[nd].end(); it++) {
        if(!visited[*it]) {
            mn = min(mn, scc(*it));
        }
        if(in_stk[*it]) {
            mn = min(mn, vfind[*it]);
        }
    }
    if(mn == vfind[nd]) {
        do {
            lead[stk[stkIdx]] = nd;
            in_stk[stk[stkIdx]] = 0;
        } while(stk[stkIdx--] != nd);
    }
    return mn;
}
int main() {
    int n, m, t, x, y;
    int i, cases = 0;
    scanf("%d", &t);
    while(t--) {
        scanf("%d %d", &n, &m);
        for(i = 1; i <= n; i++) {
            g[i].clear();
            vfind[i] = visited[i] = in_stk[i] = 0;
            lead[i] = i;
        }
        while(m--) {
            scanf("%d %d", &x, &y);
            g[x].push_back(y);
        }
        for(i = 1; i <= n; i++) {
            if(!visited[i]) {
                findIdx = 0, stkIdx = -1;
                scc(i);
            }
        }
        int indeg[10005] = {};
        for(i = 1; i <= n; i++) {
            for(vector<int>::iterator it = g[i].begin();
                it != g[i].end(); it++) {
                if(lead[*it] != *it)
                    indeg[*it]++;
                if(lead[i] != lead[*it])
                    indeg[lead[*it]]++;
            }
        }
        int ans = 0;
        for(i = 1; i <= n; i++)
            if(!indeg[i] && lead[i] == i)
                ans++;
        printf("Case %d: %d\n", ++cases, ans);
    }
    return 0;
}

台長: Morris
人氣(1,472) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA][SCC、Tarjan算法] 11838 - Come and Go
此分類上一篇:[UVA][Greedy] 10382 - Watering Grass

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文