[最小点基]LightOJ 1034-Hit the Light Switch es

4786 ワード

転送ゲート:http://lightoj.com/volume_showproblem.php?problem=1034
1034-Hit the Light Switch

PDF(English)
Statistics
Forum
Time Limit:2 second(s)
メモリLimit:32 MB
Ronju is a night-gard the“Lavishoofficebuildings Ltd.”headquarares.The oofficehas.The office has a largagagagage field in frontt of the building.So evryday,when Ronjjjjumcome to dutytythe theevininininininfefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefetythe theeeeeeeedidididididididididididit the the the therereininininininininininininininininininininininumber of lights,it is very tiring for him to walk to each and every individual light to turn it on.
ソヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘヘススススソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソソレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレレSo from now on,Ronju can just manaualy flip a few switch、and the light from those will trigger near by sensors、which will in turn light up some more nearby、and so on、graduallylight light up the whofield.
Now Ronju wonders:how many switch es he have to flip manaualy for this?
Input
Input starts with an integerT(≦15)、denoting the number of test cases.
Each case contains a blank line two integersN(1≦N≦10000)andM(0≦M≦105)、wheeNis the number of lights inthe field、andMmore lins of inputfollowowows in in thinputcase.Each of these eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeextrtrtrtrtrtrtrtrtraatttininininininininininininininininininininininininininininininininininininininininhtts up,it will trigger the lightbto turn on as well(according to their distance、brightness、sensor sensitivity、orentation and other compration factors).
Output
For each case,print the case number and minimum number of lights that Ronju must turn on manaully before all the lights in the whole field gets up.
Sample Input
Output for Sample Input
2 5 4 1 2 1 3 4 4 4 4 1 2 3 3 4 4 1 2 3 3 3
Case 1:2 Case 2:2
PROBLEM SETTER:SAMEE ZARHUR
SPECIAL THANKS:JANE ALAM JAN
向図の最小点の基があることを求めて、とても裸です.
構想:直接に強い接続+縮む点を求めて、そして入度が0の点を探していけばいいです.
コード:
#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
/**
    
**/
const int MAXN = 11111;
int low[MAXN],dfn[MAXN],belong[MAXN],deg[MAXN],ans,scc,t,n,m,depth;
vector<int> g[MAXN],gs[MAXN];
stack<int> s;
void init(){
    for(int i=0;i<MAXN;i++)g[i].clear(),gs[i].clear();
    memset(dfn,-1,sizeof(dfn));
    memset(belong,-1,sizeof(belong));
    memset(deg,0,sizeof(deg));
    ans = scc = depth = 0 ;
    while(!s.empty())s.pop();
}
void tarjan(int u){
    low[u] = dfn[u] = depth++;
    s.push(u);
    for(int i=0;i<(int)g[u].size();i++){
        int v = g[u][i];
        if(dfn[v]==-1){
            tarjan(v);
            low[u] = min(low[u],low[v]);
        }else if(belong[v]==-1){
            low[u] = min(low[u],dfn[v]);
        }
    }
    if(low[u]==dfn[u]){
        int v;
        do{
           v = s.top();
           belong[v] = scc;
           s.pop();
        }while(v!=u);
        scc++;
    }
}
void DFS(int u){
    dfn[u] = 1;
    for(int i=0;i<(int)g[u].size();i++){
        int v = g[u][i];
        if(belong[u]!=belong[v])deg[belong[v]]++;
        if(!dfn[v])DFS(v);
    }
}
void solve(){
    for(int i=0;i<scc;i++)if(!deg[i])ans++;
}
int main(){
    scanf("%d",&t);
    for(int cas=1;cas<=t;cas++){
        init();
        scanf("%d%d",&n,&m);
        while(m--){
            int a,b;
            scanf("%d%d",&a,&b);a--,b--;
            g[a].push_back(b);
        }
        for(int i=0;i<n;i++)if(dfn[i]==-1)tarjan(i);
        memset(dfn,0,sizeof(dfn));
        for(int i=0;i<n;i++)if(!dfn[i])DFS(i);
        solve();
        printf("Case %d: %d
",cas,ans); } return 0; }