POJ-1236 Network of Schools 缩点

题意:就是给我们一个网络 让我们求

1 选择最少的点传信 能够使得这个信息传遍整个网络

2 求加的最少的边 使得 加上这些边后整个图任取一个点信息就可以传到网络中任何一个店


分析: 对于1问 可以用tarjan缩点 把所有的强联通分量缩成一个点 去考虑 然后求一下出度为0的点 就是让信息传遍整个网络的点的数量 如果这里选择根据出度的数量排序用BFS把尽可能多的点标记的做法 会WA 因为用BFS去考虑的话 只考虑了出度没有考虑入度 有些点考虑不到 就是那些入度为0出度比较小的点 网络中只有搞定了这些点才能让一个信息传遍整个网络 因为入度为0的点 无论怎么考虑出度 都不会有边能够沟通到这类点 

对于2问 还是统计出入度和出度为0的点 我们考虑 对于一个网络 只要把他改造成一个强联通图 这个图中的任意亮点就都可达了

也就是解决入度为0和出度为0的点 因为入度为0的点 没人穿的到他 出度为0的点信息给他出不去 所以当我们让这两类点一对一互相联通 剩下的多余的任意连 即可沟通整个网络

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

class node implements Comparable<node>{
	int id,edge;
	node(){}
	node(int a,int b){this.id = a;this.edge = b;}
	@Override
	public int compareTo(node p) {
		// TODO Auto-generated method stub
		if(p.edge<=this.edge)return 1;
		else return -1;
	}
	
}

public class Main {
	static final int maxn = 110;
	static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
	static ArrayDeque<Integer> que = new ArrayDeque<Integer>();
	static ArrayDeque<Integer> S = new ArrayDeque<Integer>();
	static int head[] = new int[maxn*maxn];
	static int to[] = new int[maxn*maxn];
	static int next[] = new int[maxn*maxn];
	
	static boolean bok[] = new boolean[maxn];
	static boolean isS[] = new boolean[maxn];
	
	static int tag=0,cnt=0,ans1 =0 ,ans2=0,ind;
	
	static int dfn[] = new int[maxn];
	static int low[] = new int[maxn];

	static node nod[] = new node[maxn];
	static int[] id = new int[maxn];
	static int cir;
	static int in[] = new int [maxn];
	static int out1[] = new int[maxn];

	static void dfs(int x) {
		dfn[x] = low[x] = ++ind;
		S.push(x);isS[x] = true;
		for(int i=head[x];i!=-1;i = next[i]) {
			int t=to[i];
			if(dfn[t]==0) {
				dfs(t);
				low[x] = Math.min(low[t], low[x]);
			}
			else if(isS[t])
				low[x] = Math.min(low[x],dfn[t]);
		}
		if(dfn[x]==low[x]){
			ans2++;
			++cir;
			while(true){
				int t;
				if(!S.isEmpty()) {
					t = S.peek();
					S.pop();isS[t] = false;
					id[t] = cir;					
					if(t==x)break;
				}
			}
		}
	}	
	static void addEdge(int x,int t) {	
		to[tag] = t;
		next[tag] = head[x];
		head[x] = tag++;
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(new BufferedInputStream(System.in));
		while(sc.hasNext()) {
			int n = sc.nextInt();
			Arrays.fill(head,-1);
			Arrays.fill(bok, false);
			Arrays.fill(isS, false);
			Arrays.fill(dfn, 0);
			Arrays.fill(low, 0);
			
			Arrays.fill(in,0);
			Arrays.fill(out1, 0);
			
			cir = tag=cnt=ans1=ans2=ind=0;
			
			for(int i=1;i<=n;i++) {
				if(nod[i]==null)nod[i] = new node(i,0);
				else {nod[i].id = i;nod[i].edge=0;}
				while(true) {
					int t = sc.nextInt();
					if(t==0)break;
					addEdge(i,t);		
				}			
			}
			for(int i=1;i<=n;i++) {
				if(dfn[i]==0) {
					S.clear();
					dfs(i);
				}
			}
			
			for(int i=1;i<=n;i++) {
				for(int j = head[i];j!=-1;j=next[j]){
					int t = to[j];
					if(id[t]!=id[i]){
						in[id[t]]++;
						out1[id[i]]++;
					}
				}
			}
			
			int Iy = 0;
			for(int i=1;i<=cir;i++)
				if(in[i]==0) {
					ans1++;
				}else if(out1[i]==0) {
					Iy++;
				}
			
			
			
			out.println(ans1);
			if(cir==1)out.println(0);
			else out.println(Math.max(ans1, Iy));
			out.flush();			
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_33859479/article/details/80432674