The King ' s problemTime
limit:2000/1000 MS (java/others) Memory limit:65536/32768 K (java/others)
Total submission (s): 2085 Accepted Submission (s): 741
Problem DescriptionIn The Kingdom of Silence, the king has a new problem. There is N cities in the kingdom and there is M directional roads between the cities. That means that if there are a road from U to V, and you can only go from the city u to City v, and can ' t go from the City v to the city U. In order to rule he kingdom more effectively, the king want to divide he kingdom into several states, and all city mus T belong to exactly one state.What's more , for each pair of the city (U, v), if there is one-to-go from U-V and go from V to U, (U, v) has to be Long to a same state. And the king must insure that in each state we can ether go from u to V or go from V to u between every pair of cities (U, V) without passing any city which belongs to other state.
Now the king asks-your help, he wants to know the least number of states he has to divide the kingdom into.
Inputthe first line contains a single integer T, the number of test cases. And then followed T cases.
The first line for each case contains integers n, m (0 < n <= 5000,0 <= m <= 100000), the number of cities And roads in the kingdom. The next m lines each contains the integers u and V (1 <= u, v <= N), indicating that there was a road going from CIT Y u to City v.
Outputthe output should contain T lines. For each test case, you should just output a integer which is the least number of states the king has to divide into.
Sample Input
13 21 21 3
Sample Output
2
Source2011 multi-university Training Contest 3-host by BIT
Recommendlcy
Test instructions: N Cities M-bar has an edge, divides these cities into several states, the principle is (1) you and V can reach each other if both of them must be in the same state (2) in the same state as any two cities U and V to meet u can reach V or V can reach U. What is the minimum number of States to ask?
Idea: First use the Tarjan algorithm to shrink the point, on the graph after the contraction point to match the binary graph, and finally find the minimum path coverage = Strong connectivity number-the maximum number of matches.
Can look at:
http://blog.csdn.net/hellobabygogo3/article/details/7900812
Http://www.cnblogs.com/ka200812/archive/2011/07/31/2122641.html
Code:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include < cmath> #include <string> #include <map> #include <stack> #include <vector> #include <set > #include <queue> #pragma comment (linker, "/stack:102400000,102400000") #define PI ACOs ( -1.0) #define EPS 1e-6# Define Lson rt<<1,l,mid#define Rson rt<<1|1,mid+1,r#define FRE (i,a,b) for (i = A; I <= b; i++) #define FREE ( I,A,B) for (i = A, I >= b; i--) #define FRL (i,a,b) for (i = A; I < b; i++) #define FRLL (i,a,b) for (i = A; i > b; i-- ) #define MEM (T, v) memset ((t), V, sizeof (t)) #define SF (n) scanf ("%d", &n) #define SFF (A, b) scanf ("%d%d", &a, &b) #define SFFF (a,b,c) scanf ("%d%d%d", &a, &b, &c) #define PF Printf#define DBG PF ("hi\n") typedef long long ll;using namespace std; #define INF 0x3f3f3f3f#define mod 1000000009const int maxn = 1005;const int MAXN = 5005;const int maxm = 100010;int n,m;struct edge{int to,next;} Edge[maxm],e[maxm];int head[maxn],tot;int low[maxn],dfn[maxn],belong[maxn],stack[maxn];int Index,scc,top;bool Inq[ Maxn];int un,vn;int linker[maxn];bool used[maxn];int hed[maxn],num;void init () {tot=0;num=0; memset (hed,-1,sizeof (hed)); memset (head,-1,sizeof (Head));} void Add (int u,int v) {e[num].to=v; E[num].next=hed[u]; hed[u]=num++;} void Addedge (int u,int v) {edge[tot].to=v; Edge[tot].next=head[u]; head[u]=tot++;} void Tarjan (int u) {int V; Low[u]=dfn[u]=++index; Stack[top++]=u; Inq[u]=true; for (int i=head[u];i+1;i=edge[i].next) {v=edge[i].to; if (! Dfn[v]) {Tarjan (v); if (Low[u]>low[v]) low[u]=low[v]; } else if (Inq[v]&&low[u]>dfn[v]) low[u]=dfn[v]; } if (Low[u]==dfn[u]) {scc++; do{V=stack[--top]; Inq[v]=false; BELONG[V]=SCC; }while (V!=u); }}void solve (int N) { memset (dfn,0,sizeof (DFN)); memset (inq,false,sizeof (INQ)); Index=scc=top=0; for (int i=1;i<=n;i++) if (! Dfn[i]) Tarjan (i); for (int u=1;u<=n;u++) {for (int i=head[u];~i;i=edge[i].next) {int v=edge[i].to; if (Belong[u]==belong[v]) continue; Add (Belong[u],belong[v]); }} UN=VN=SCC;} bool Dfs (int u) {for (int i=hed[u];~i;i=e[i].next) {int v=e[i].to; if (!used[v]) {used[v]=true; if (linker[v]==-1| | DFS (Linker[v])) {linker[v]=u; return true; }}} return false;} int Hungary () {int ans=0; memset (LINKER,-1,SIZEOF (linker)); for (int i=1;i<=un;i++) {memset (used,false,sizeof (used)); if (Dfs (i)) ans++; if (Ans==un) break; } return ans; int main () {#ifndef Online_judge freopen ("C:/users/lyf/desktop/in.txt", "R", stdin), #endif int i,j,t,u,v; SF (t); while (t--) {SFF (n,m); Init (); for (i=0;i<m;i++) {SFF (u,v); Addedge (U,V); } solve (n); int ans=hungary (); printf ("scc=%d \ n", SCC); printf ("%d\n", Scc-ans); } return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
The King's problem (HDU 3861 Strong connected indent + Minimum path overlay)