CodeChef Counting on a directed graph

Counting on a directed graph Problem Code: GRAPHCNT

All submissions for this problem are available.

Read problems statements in Mandarin Chineseand Russian.

Given an directed graph with N nodes (numbered from 1 to N) and M edges, calculate the number of unordered pairs (X, Y) such there exist two paths, one from node 1 to node X, and another one from node 1 to node Y, such that they don‘t share any node except node 1.

Input

There is only one test case in one test file.

The first line of each test case contains two space separated integers N, M. Each of the next M lines contains two space separated integers u, v denoting a directed edge of graph G, from node u to node v. There are no multi-edges and self loops in the graph.

Output

Print a single integer corresponding to the number of unordered pairs as asked in the problem..

Constraints and Subtasks

  • 1 ≤ N ≤ 105
  • 0 ≤ M ≤ 5 * 105

Subtask 1: (30 points)

Subtask 2: (20 points)

  • N * M ≤ 50000000

Subtask 3 (50 points)

  • No additional constraints

Example

Input:
6 6
1 2
1 3
1 4
2 5
2 6
3 6

Output:
14

Explanation

There are 14 pairs of vertices as follows: 
(1,2) 
(1,3) 
(1,4) 
(1,5) 
(1,6) 
(2,3) 
(2,4) 
(2,6) 
(3,4) 
(3,5) 
(3,6) 
(4,5) 
(4,6) 
(5,6)

Author:5★ztxz16

Tester:7★kevinsogo

Editorial:http://discuss.codechef.com/problems/GRAPHCNT

Tags:dominatormay15medium-hardztxz16

Date Added:25-03-2015

Time Limit:2 secs

Source Limit:50000 Bytes

Languages:ADA, ASM, BASH, BF, C, C99 strict, CAML, CLOJ, CLPS, CPP 4.3.2, CPP 4.9.2, CPP14, CS2, D, ERL, FORT, FS, GO, HASK, ICK, ICON, JAVA, JS, LISP clisp, LISP sbcl, LUA, NEM, NICE, NODEJS, PAS fpc, PAS gpc, PERL, PERL6, PHP, PIKE, PRLG, PYPY, PYTH, PYTH 3.4, RUBY, SCALA, SCM chicken, SCM guile, SCM qobi, ST, TCL, TEXT, WSPC

题意:

https://s3.amazonaws.com/codechef_shared/download/translated/MAY15/mandarin/GRAPHCNT.pdf

分析:

建出支配树,然后统计1号节点的每个儿子内部点对数量,这就是不合法的点对数量,用总的点对数量减去不合法的就好了...

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<stack>
using namespace std;

const int maxn=100000+5,maxm=500000+5;

int n,m,tot,f[maxn],fa[maxn],id[maxn],dfn[maxn],siz[maxn],node[maxn],semi[maxn],idom[maxn];
long long ans;

stack<int> dom[maxn];

struct M{

	int cnt,hd[maxn],to[maxm],nxt[maxm];

	inline void init(void){
		cnt=0;
		memset(hd,-1,sizeof(hd));
	}

	inline void add(int x,int y){
		to[cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt++;
	}

}G,tr;

inline bool cmp(int x,int y){
	return dfn[semi[x]]<dfn[semi[y]];
}

inline int find(int x){
	if(f[x]==x)
		return x;
	int fx=find(f[x]);
	node[x]=min(node[f[x]],node[x],cmp);
	return f[x]=fx;
}

inline void dfs(int x){
	dfn[x]=++tot;id[tot]=x;
	for(int i=tr.hd[x];i!=-1;i=tr.nxt[i])
		if(!dfn[tr.to[i]])
			dfs(tr.to[i]),fa[tr.to[i]]=x;
}

inline void LT(void){
	dfs(1);dfn[0]=tot<<1;
	for(int i=tot,x;i>=1;i--){
		x=id[i];
		if(i!=1){
			for(int j=G.hd[x],v;j!=-1;j=G.nxt[j])
				if(dfn[G.to[j]]){
					v=G.to[j];
					if(dfn[v]<dfn[x]){
						if(dfn[v]<dfn[semi[x]])
							semi[x]=v;
					}
					else{
						find(v);
						if(dfn[semi[node[v]]]<dfn[semi[x]])
							semi[x]=semi[node[v]];
					}
				}
			dom[semi[x]].push(x);
		}
		while(dom[x].size()){
			int y=dom[x].top();dom[x].pop();find(y);
			if(semi[node[y]]!=x)
				idom[y]=node[y];
			else
				idom[y]=x;
		}
		for(int j=tr.hd[x];j!=-1;j=tr.nxt[j])
			if(fa[tr.to[j]]==x)
				f[tr.to[j]]=x;
	}
	for(int i=2,x;i<=tot;i++){
		x=id[i];
		if(semi[x]!=idom[x])
			idom[x]=idom[idom[x]];
	}
	idom[id[1]]=0;
}

signed main(void){
	tr.init();G.init();
	scanf("%d%d",&n,&m);
	for(int i=1,x,y;i<=m;i++)
		scanf("%d%d",&x,&y),tr.add(x,y),G.add(y,x);
	for(int i=1;i<=n;i++)
		f[i]=node[i]=i;
	LT();ans=1LL*tot*(tot-1);
	for(int i=tot;i>=2;i--){
		siz[id[i]]++;
		if(idom[id[i]]!=1)
			siz[idom[id[i]]]+=siz[id[i]];
		else
			ans-=1LL*siz[id[i]]*(siz[id[i]]-1);
	}
	ans>>=1;
	printf("%lld\n",ans);
	return 0;
}

  



By NeighThorn

时间: 2024-10-07 05:02:27

CodeChef Counting on a directed graph的相关文章

[email&#160;protected] Find if there is a path between two vertices in a directed graph

Given a Directed Graph and two vertices in it, check whether there is a path from the first given vertex to second. For example, in the following graph, there is a path from vertex 1 to 3. As another example, there is no path from 3 to 0. We can eith

[LintCode] Find the Weak Connected Component in the Directed Graph

Find the number Weak Connected Component in the directed graph. Each node in the graph contains a label and a list of its neighbors. (a connected set of a directed graph is a subgraph in which any two vertices are connected by direct edge path.) Exam

Geeks - Detect Cycle in a Directed Graph 判断图是否有环

Detect Cycle in a Directed Graph 判断一个图是否有环,有环图如下: 这里唯一注意的就是,这是个有向图, 边组成一个环,不一定成环,因为方向可以不一致. 这里就是增加一个数组保存当前已经访问过的路径信息 recStack[]: 而visited[]数组是访问过的点的信息,两者作用是不一样的. 知道这个知识点,这道题就很容易了. 原文: http://www.geeksforgeeks.org/detect-cycle-in-a-graph/ #include <st

[CareerCup] 4.2 Route between Two Nodes in Directed Graph 有向图中两点的路径

4.2 Given a directed graph, design an algorithm to find out whether there is a route between two nodes. LeetCode和CareerCup中关于图的题都不是很多,LeetCode中只有三道,分别是Clone Graph 无向图的复制,Course Schedule 课程清单 和 Course Schedule II 课程清单之二.目前看来CareerCup中有关图的题在第四章中仅此一道,这是

Leetcode: Graph Valid Tree &amp;&amp; Summary: Detect cycle in directed graph and undirected graph

Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree. For example: Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return tru

Geeks - Detect Cycle in a Directed Graph 推断图是否有环

Detect Cycle in a Directed Graph 推断一个图是否有环,有环图例如以下: 这里唯一注意的就是,这是个有向图, 边组成一个环,不一定成环,由于方向能够不一致. 这里就是添加一个数组保存当前已经訪问过的路径信息 recStack[]: 而visited[]数组是訪问过的点的信息,两者作用是不一样的. 知道这个知识点,这道题就非常easy了. 原文: http://www.geeksforgeeks.org/detect-cycle-in-a-graph/ #includ

Directed Graph Loop detection and if not have, path to print all path.

这里总结针对一个并不一定所有点都连通的general directed graph, 去判断graph里面是否有loop存在, 收到启发是因为做了[LeetCode] 207 Course Schedule_Medium tag: BFS, DFS, 这个题实际上就是监测directed graph里面是否有loop存在. 我在网上看了比较经典的做法为DFS, 并且用三个set去标志not visited点,(0), 正在visiting的点(-1), 已经visited过的点(1), 我结合这

Find the Weak Connected Component in the Directed Graph

Description Find the number Weak Connected Component in the directed graph. Each node in the graph contains a label and a list of its neighbors. (a weak connected component of a directed graph is a maximum subgraph in which any two vertices are conne

普林斯顿大学《算法II》第二周学习笔记 Directed Graph

有向图的遍历和无向图的遍历类似,主要是DFS和BFS. 对于DAG(Directed Acyclic Graph),还有一个很重要的拓扑的概念,拓扑排序的倒序可以用Depth-first search来生成,类似二叉树的后序遍历. 见Depthfirst Order in Algs4 private void dfs(Digraph G, int v) { marked[v] = true; pre[v] = preCounter++; preorder.enqueue(v); for (int