UVA 11770 — Lighting Away 强连通+拓扑

来源:互联网 发布:正元恒邦手机分析软件 编辑:程序博客网 时间:2024/06/07 04:52

题意:有n盏灯,m个关联;

    a点亮了b必定点亮;

    问至少要开几盏灯才能使所有的灯点亮;


思路:用强连通缩点,然后拓扑求入度为0得点;


#include<stdio.h>#include<vector>#include<string.h>#include<iostream>#include<algorithm>using namespace std;const int N = 10005;int head[N], vis[N];int DFN[N], low[N], belong[N], stack[N];int n, m, edgenum;int top, Time, taj;struct node{int from, to, nex;bool sign;}edge[100005];void add(int u, int v){edge[edgenum].from = u;edge[edgenum].to = v;edge[edgenum].sign = false;edge[edgenum].nex = head[u];head[u] = edgenum++;}vector<int>bcc[N];void tarjan(int u, int fa){DFN[u] = low[u] = Time++;vis[u] = 1;stack[top++] = u;for(int i = head[u];i!=-1;i = edge[i].nex){int v = edge[i].to;if(DFN[v] == -1){tarjan(v, u);low[u] = min(low[u], low[v]);if(DFN[u]<low[v])edge[i].sign = 1;}else if(vis[v])low[u] = min(low[u], DFN[v]);}if(low[u] == DFN[u]){  taj ++ ; bcc[taj].clear();while(1){int now = stack[--top];  vis[now] = 0; belong[now] = taj;bcc[taj].push_back(now);if(now == u)break;}}}vector<int>G[N];int du[N];void suodian(){memset(du, 0, sizeof(du));for(int i = 1;i<=taj;i++)G[i].clear();for(int i = 0;i<edgenum;i++){int u = belong[edge[i].from];int v = belong[edge[i].to];if(u!=v){G[u].push_back(v);du[v]++;}}}void tarjan_init(int all){memset(DFN, -1, sizeof(DFN));memset(low, -1, sizeof(low));memset(vis, 0, sizeof(vis));Time = top = taj = 0;for(int i = 1;i<=all;i++){if(DFN[i] == -1)tarjan(i, i);}}int main(){int cas;int t = 0;scanf("%d", &cas);while(cas--){memset(head, -1, sizeof(head));edgenum = 0;scanf("%d%d", &n, &m);while(m--){int u, v;scanf("%d%d", &u, &v);add(u, v);}tarjan_init(n);suodian();int con = 0;for(int i = 1;i<=taj;i++){if(du[i] == 0)con++;}printf("Case %d: %d\n", ++t, con);}return 0;}



0 0
原创粉丝点击