Title Link: Http://codeforces.com/contest/505/problem/D
Main topic:In one figure, there are n vertices, giving the m pair number (U,V) to indicate that the vertex u and vertex v must be connected directly or indirectly, so that you can construct a graph with a minimum number of edges required for the output. Analysis:Without a doubt, n vertices, we can use up to n edges, so that n vertices form a ring to satisfy all the situation (any two points are connected), but this is not necessarily the least side.So we also need to find a way to determine the minimum number of edges required.First of all, we use the point pair of the topic to build the map, get figure G. For the weak Unicom component in G, there are two kinds of situations to discuss:1. There is no ring in this weak unicom component. So we can use topological ordering to turn this graph into a chain, assuming that there are N1 vertices in this component, then no doubt,The required number of edges is n1-1. 2. There is a link in this weak unicom component. Assuming that there are N2 vertices in this component,so we can use the N2 edge to make this n2 vertex a ring,With the above analysis, our job now is to determine if there are no loops in each of the weak Unicom components. The method of judging the ring, that is to detect the point where the number of strong connected components is equal to 1, if greater than 1, then that the component has a ring, if equal to 1, then there is no ring in this component.
Code:
#include <iostream> #include <cstdio> #include <vector> #include <cstring>using namespace std;# Define N 100010vector<int> g[n];vector<int> rg[n];vector<int> vs;bool used[N];int cmp[N];int n,m; void Add_edge (int from,int to) {g[from].push_back (to); Rg[to].push_back (from);} void Dfs (int v) {used[v]=1; for (int i=0;i<g[v].size (); i++) if (!used[g[v][i]]) DFS (g[v][i]); Vs.push_back (v);} void Rdfs (int v,int k) {used[v]=1; Cmp[v]=k; for (int i=0;i<rg[v].size (); i++) if (!used[rg[v][i]]) Rdfs (rg[v][i],k);} int SCC () {memset (used,0,sizeof (used)); Vs.clear (); for (int v=0;v<n;v++) if (!used[v]) Dfs (v); memset (used,0,sizeof (used)); int k=0; for (int i=vs.size () -1;i>=0;i--) if (!used[vs[i]]) Rdfs (vs[i],k++); return k;} int Cmpsize[n];bool DFS2 (int v) {used[v]=1; BOOL Ans= (cmpsize[cmp[v]]==1); for (int i=0;i<g[v].size (); i++) { if (!used[g[v][i]]) ans &= (DFS2 (G[v][i]) ==1); } for (int i=0;i<rg[v].size (); i++) {if (!used[rg[v][i])) ans &= (DFS2 (Rg[v][i]) ==1); } return ans; int main () {while (~scanf ("%d%d", &n,&m)) {memset (cmpsize,0,sizeof (cmpsize)); for (int i=0;i<n;i++) rg[i].clear (), g[i].clear (); for (int i=0;i<m;i++) {int u,v; scanf ("%d%d", &u,&v); Add_edge (U-1,v-1); } SCC (); memset (used,0,sizeof (used)); for (int i=0;i<n;i++) cmpsize[cmp[i]]++; int ans=n; for (int i=0;i<n;i++) {if (!used[i]) ans-= DFS2 (i); } cout<<ans<<endl; } return 0;}
Codeforces Round #286 Div.2 D 505D. Mr Kitayuta ' s technology "strong connectivity components, weak unicom components"