Link: click here
Test instructions
Campus Network time limit: theMs | Memory Limit:65535KB Difficulty:5
-
Describe
-
Nanyang Institute of Technology, a total of M-series, respectively numbered 1~m, wherein the departments reached a certain agreement, if a department has new software available, the department will allow some other departments to copy and use the software. However, the permissible relationship is one-way, that is: A system allows B to use the software of a, B may not necessarily allow a to use the software B.
Now, please write a program, according to the agreement between the various departments to calculate the minimum number of two lines to add the allowable relationship between the system, in order to make any one of the software used, all other departments are also available software.
-
Input
-
The first line enters an integer T, which represents the number of groups of test data (T<10)
The first line of each set of test data is an integer m representing a total of M-Systems (2<=M<=100).
The subsequent M-line, with a number of integers in each row, indicates that line I allows the system to replicate and use the software of the system I. The end of each line is a 0, indicating the end of the bank's input. If a department does not allow any other department to use the system software, the bank has only one 0.
-
Output
-
For each set of test data, the minimum number of such allowable relationships that need to be added is output.
-
Sample input
-
152 4 3 04 5 0001 0
-
Sample output
-
2
The first feeling of the problem is related to the degree of the figure, finally wrote a bit, the data comparison of water.
Thinking: Statistics into the degree and out of the line, a vertex of both the degree and the degree that the vertex does not need to add lines, and finally take the maximum value comparison.
Code:
#include <math.h> #include <queue> #include <deque> #include <vector> #include <stack># Include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> #include < Iostream> #include <algorithm>using namespace std; #define MAX (b) A>b?a:b#define Min (A, b) a>b?b:a# Define MEM (A, B) memset (A,b,sizeof (a)) int dir[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};const double EPS = 1e-6;const double Pi = ACOs ( -1.0); static const int INF = ~0u >> 2;static const int MAXN = 102;int Mapp[maxn][maxn],comeder[maxn],outder[ma Xn];int n,m,i,j,cas,cnt;void input () {for (i=1; i<=n; i++) while (~scanf ("%d", &m), m) {MA Pp[i][m]=1; } for (I=1, i<=n; i++) for (j=1; j<=n; J + +) {if (Mapp[i][j]) {C Omeder[j]=1; Outder[i]=1; }}}void output () {int sum1=0,sum2=0; for (I=1; i<=n; i++) {if (comeder[i]==0) sum1++; if (outder[i]==0) sum2++; } printf ("%d\n", Max (SUM1,SUM2));} int main () {scanf ("%d", &cas); while (cas--) {int sum; scanf ("%d", &n); Mem (mapp,0), mem (comeder,0), mem (outder,0); Input (); Output (); } return 0;}
Later look at the puzzle, the original is strongly connected to shrink point Targan algorithm, strong connectivity to shrink point has not learned, first affixed to someone else's code, research ~ ~
Parse (GO): Click to open link
Tarjan algorithm Detailed
function
One of the uses of the Tarjan algorithm is to ask for a strongly connected component in a graph g= (v,e). The strongly connected component refers to a sub-graph in which the vertices can reach each other in the graph G. If a strongly connected component is not fully contained by any other strong component, then the strongly connected component is the strongly connected component.
"Algorithmic thinking"
Using DFS to traverse each vertex in G, pass Dfn[i] represents the time at which the DFS reaches vertex i, and low[i] represents the vertex to which I can reach the minimum time directly or indirectly. (Low[i in practice is not necessarily minimal, but does not affect the final result of the program)
When the program starts, order is initialized to 0, and when Dfs traverses to V, the low[v]=dfn[v]=order++,v into the stack (where the stack is not the one that the system gets out of when the DFS is recursive) scans the vertex K directly reached by V, if K has not been accessed then DFS traversal K, Low[v]=min (Low[v],low[k]); If k is in the stack, then Low[v]=min (Low[v],dfn[k]) (which is where low[v] is not necessarily the smallest, but does not affect the low[v here]). After scanning all k, if LOW[V]=DFN[V], the vertices of the stack V and above v all out of the stack, and just out of the stack is a very strong connected component.
"Probable proof."
1. In the stack, when Dfs traverses to V and has traversed the vertices that V can reach directly, V must be able to reach the vertices above the stack v Low[v]=dfn[v]:
Because when Dfs traverses to V, and DFS recursively calls the vertices that V can reach directly (assuming there is no LOW=DFN above), then if LOW[V]=DFN[V] is found, the vertices above the stack must have just been pushed forward from the vertex v recursive call, so v must be able to reach those vertices.
2. DFS traversal, if you have traversed the V can be directly reached vertex and Low[v]=dfn[v], we know that V can reach the top of the stack V, the vertices of the low must be less than their own dfn, or will be out of the stack, will not be less than dfn[v], otherwise low [v] Must be less than dfn[v], so the stack V with its vertices above the V is a strong connected component, if it is not a strongly connected component Low[v] must be less than dfn[v] (here is no longer detailed), so the stack V with its vertices of more than a sub-graph is a very strong connected component.
"Complexity of Time"
Because all the points are just once in the stack, all the edges are accessed once, so the time complexity is O (n+m)
The code is as follows:
Strong connectivity Component Indent # include <iostream> #include <cstring> #include <cstdio> #include <stack>using namespace Std;const int MAX = 105;int map[max][max];int Low[max], Dfn[max], In[max], Out[max], Instack[max], T[max];int N, Order, res, ans;stack<int> s;void init () {memset (map, 0, sizeof (map)); memset (Low, 0, sizeof (low)); memset (DFN, 0, sizeof (DFN)); memset (in, 0, sizeof (in)); memset (out, 0, sizeof (out)); memset (instack, 0, sizeof (instack)); memset (t, 0, sizeof (t)); while (! S.empty ()) S.pop (); res = 0; order = 0;} int min (int x, int y) {return x < y x:y;} void tr (int u) {int V; Dfn[u] = low[u] = ++order; Instack[u] = 1; S.push (U); for (int i = 1; I <= n; i++) {if (Map[u][i]) {if (! Dfn[i]) {tr (i); Low[u] = min (Low[u], low[i]); } else if (Instack[i]) low[u] = min (Low[u], dfn[i]); }} if (dfn[u] = = Low[u]) {++res; Res represents the number of strongly connected components do {v=s.top (); S.pop (); INSTACK[V] = 0; T[V] = res; }while (v! = u); }}void Tarjan () {for (int i = 1; I <= n; i++) if (! Dfn[i]) TR (i);} void Solve () {for (int i = 1;i <= N, i++) {for (int j = 1;j <= N; j + +) if (Map[i][j])//Statistics The degrees and degrees of indentation of each strongly connected component {++in[t[i]]; ++OUT[T[J]]; }} int xx, yy; xx = yy = 0; for (int i = 1; I <= res; i++) {if (in[i]==0) xx++; else if (out[i]==0) yy++; } ans = xx > yy? Xx:yy; The result is a}int with a scale of 0 or a size of 0 in the direction of the indented point, the main () {int T, x; scanf ("%d", &t); while (t--) {init (); scanf ("%d", &n); for (int i = 1; I <= n; i++) {while (scanf ("%d", &x), x) map[i][x] = 1; } Tarjan (); Solve (); if (res == 1) printf ("0\n"); else printf ("%d\n", ans); } return 0;}
NYOJ-120 Campus Network &&poj 1236 (strong connected scaling Targan algorithm)