标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 15211 | Accepted: 6040 |
Description
Input
Output
Sample Input
5 2 4 3 0 4 5 0 0 0 1 0
Sample Output
1 2
题意:
N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输,问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。2,至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。
给定一个有向图,求:
1) 至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点
2) 至少要加多少条边,才能使得从任何一个顶点出发,都能到达全部顶点
思路:
问题1答案就是入度为0的点的个数。
在DAG上要加几条边,才能使得DAG变成强连通的,问题2的答案就是多少
加边的方法:
要为每个入度为0的点添加入边,为每个出度为0的点添加出边
假定有 n 个入度为0的点,m个出度为0的点,如何加边?
把所有入度为0的点编号 0,1,2,3,4 ....N -1
每次为一个编号为i的入度0点可达的出度0点,添加一条出边,连到编号为(i+1)%N 的那个出度0点,
这需要加n条边若 m <= n,则加了这n条边后,已经没有入度0点,则问题解决,一共加了n条边
若 m > n,则还有m-n个入度0点,则从这些点以外任取一点,和这些点都连上边,即可,这还需加m-n条边。所以,max(m,n)就是第二个问题的解。
/* * Author: sweat123 * Created Time: 2016/6/25 15:49:19 * File Name: main.cpp */ #include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<string> #include<vector> #include<cstdio> #include<time.h> #include<cstring> #include<iostream> #include<algorithm> #define INF 1<<30 #define MOD 1000000007 #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define pi acos(-1.0) using namespace std; const int MAXN = 10010; struct node{ int from; int to; int next; }edge[MAXN*10]; int pre[MAXN],vis[MAXN],dfn[MAXN],low[MAXN],n,m,ind; int f[MAXN],siz[MAXN],num,dep,out[MAXN],in[MAXN]; stack<int>s; void add(int x,int y){ edge[ind].from = x; edge[ind].to = y; edge[ind].next = pre[x]; pre[x] = ind ++; } void dfs(int rt){ dfn[rt] = low[rt] = ++dep; vis[rt] = 1; s.push(rt); for(int i = pre[rt]; i != -1; i = edge[i].next){ int t = edge[i].to; if(!dfn[t]){ dfs(t); low[rt] = min(low[rt],low[t]); } else if(vis[t]){ low[rt] = min(low[rt],dfn[t]); } } if(low[rt] == dfn[rt]){ ++num; while(!s.empty()){ int tp = s.top(); s.pop(); vis[tp] = 0; f[tp] = num; siz[num] ++; if(tp == rt)break; } } } void setcc(){ num = 0; dep = 0; memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); for(int i = 1; i <= n; i++){ if(!dfn[i]){ dfs(i); } } int ret = ind; for(int i = 0; i < ret; i++){ int x = f[edge[i].from]; int y = f[edge[i].to]; if(x == y)continue; out[x] ++; in[y] ++; } int ans1,ans2; ans1 = ans2 = 0; for(int i = 1; i <= num; i++){ if(in[i] == 0){ ans1 ++; } if(out[i] == 0){ ans2 ++; } } ans2 = max(ans2,ans1); if(num == 1)ans2 = 0; printf("%d\n%d\n",ans1,ans2); } int main(){ while(~scanf("%d",&n)){ ind = 0; while(!s.empty())s.pop(); memset(pre,-1,sizeof(pre)); memset(vis,0,sizeof(pre)); memset(f,-1,sizeof(f)); for(int i = 1; i <= n; i++){ while(1){ int x; scanf("%d",&x); if(x == 0)break; add(i,x); } } setcc(); } return 0; }
标签:
原文地址:http://www.cnblogs.com/sweat123/p/5616462.html