国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Mr. Kitayuta's Technology CodeForces - 505D(并查集+拓撲排序或dfs找環) 題解

2019-11-08 01:33:38
字體:
來源:轉載
供稿:網友

題目 Shuseki Kingdom is the world’s leading nation for innovation and technology. There are n cities in the kingdom, numbered from 1 to n.

Thanks to Mr. Kitayuta’s research, it has finally become possible to construct teleportation pipes between two cities. A teleportation pipe will connect two cities unidirectionally, that is, a teleportation pipe from city x to city y cannot be used to travel from city y to city x. The transportation within each city is extremely developed, therefore if a pipe from city x to city y and a pipe from city y to city z are both constructed, people will be able to travel from city x to city z instantly.

Mr. Kitayuta is also involved in national politics. He considers that the transportation between the m pairs of city (ai,?bi) (1?≤?i?≤?m) is important. He is planning to construct teleportation pipes so that for each important pair (ai,?bi), it will be possible to travel from city ai to city bi by using one or more teleportation pipes (but not necessarily from city bi to city ai). Find the minimum number of teleportation pipes that need to be constructed. So far, no teleportation pipe has been constructed, and there is no other effective transportation between cities.

Input The first line contains two space-separated integers n and m (2?≤?n?≤?105,?1?≤?m?≤?105), denoting the number of the cities in Shuseki Kingdom and the number of the important pairs, respectively.

The following m lines describe the important pairs. The i-th of them (1?≤?i?≤?m) contains two space-separated integers ai and bi (1?≤?ai,?bi?≤?n,?ai?≠?bi), denoting that it must be possible to travel from city ai to city bi by using one or more teleportation pipes (but not necessarily from city bi to city ai). It is guaranteed that all pairs (ai,?bi) are distinct.

Output PRint the minimum required number of teleportation pipes to fulfill Mr. Kitayuta’s purpose.

Example Input 4 5 1 2 1 3 1 4 2 3 2 4 Output 3 Input 4 6 1 2 1 4 2 3 2 4 3 2 3 4 Output 4


題目大意就是城市之間可以修單向的瞬時傳送門,現在給出需求(需要那個城市可以到達娜個城市),問你最少需要修多少個傳送通道,首先可以知道,對于需求構成的一個聯通塊,若連通塊有環,只需要把連通塊里的點修出一個單項環,任意點就可以互相達到了,若無環,只需要修n-1條路就可以滿足需求了。 所以我們只需要用并查集找出所有的連通塊,然后對每個連通塊判斷環就行,我用了拓撲排序和dfs找環兩種方法來做。 首先是拓撲排序,拓撲排序本身是針對無環有向圖的,通過不斷把沒有入度的點入隊來實現,而若有環,則環上的點始終無法入隊,最后處理完它們的入度也不會變成零,這樣就很容易找出環了。 dfs找環的方法就是對點賦予狀態,0表示沒訪問過,1表示這個點及其相連的連通塊都已經訪問過了,-1則表示這個點正在對其dfs深搜訪問,若一個點狀態為-1又被再一次訪問到,那么這肯定就是一個環了。

1.拓撲排序

#include<iostream>#include<string.h>#include<stdio.h>#include<string>#include<vector>#include<algorithm>#include<queue>#include<set>#include<stack>using namespace std;int f[100005];int n, m;vector<int > e[100005];queue<int> que;int F(int x){ if (f[x] == x)return x; return f[x] = F(f[x]); }bool H[100005];int lt[100005];bool vis[100005];int deg[100005];void func(){ while (!que.empty()){ int cnt = que.front(); que.pop(); for (int i = 0; i < e[cnt].size(); i++){ deg[e[cnt][i]]--; if (deg[e[cnt][i]] == 0)que.push(e[cnt][i]); } }}int main(){ int x, y; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++)f[i] = i; for (int i = 0; i < m; i++){ scanf("%d%d", &x, &y); e[x].push_back(y); deg[y]++; f[F(x)] = F(y); } for (int i = 1; i <= n; i++){ lt[F(i)]++; if (deg[i] == 0)que.push(i); } func(); int ans = 0; for (int i = 1; i <= n; i++){ if (deg[i] != 0)H[F(i)] = 1; } for (int i = 1; i <= n; i++){ if (f[i] == i){ if (H[i])ans += lt[i]; else{ ans += lt[i] - 1; } } } printf("%d", ans); return 0;}

2.DFS找環

#include<iostream>#include<string.h>#include<stdio.h>#include<string>#include<vector>#include<algorithm>#include<queue>#include<set>#include<stack>using namespace std;int f[100005];int n, m;vector<int > e[100005];queue<int> que;int F(int x){ if (f[x] == x)return x; return f[x] = F(f[x]); }bool H[100005];int lt[100005];bool vis[100005];int c[100005];void dfs(int cnt){ c[cnt] = -1; for (int i = 0; i < e[cnt].size(); i++){ int cur = e[cnt][i]; if (c[cur] == -1){ H[F(cur)] = 1; break; } else if (c[cur] == 0){ dfs(cur); } } c[cnt] = 1;}int main(){ int x, y; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++)f[i] = i; for (int i = 0; i < m; i++){ scanf("%d%d", &x, &y); e[x].push_back(y); //deg[y]++; f[F(x)] = F(y); } for (int i = 1; i <= n; i++){ lt[F(i)]++; if (c[i] == 0)dfs(i); //if (deg[i] == 0)que.push(i); }// func(); int ans = 0; for (int i = 1; i <= n; i++){ if (f[i] == i){ if (H[i])ans += lt[i]; else{ ans += lt[i] - 1; } } } printf("%d", ans); return 0;}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 平乡县| 武定县| 盐津县| 板桥市| 甘德县| 卢龙县| 太原市| 乐安县| 上饶市| 宁城县| 长葛市| 许昌市| 怀来县| 浪卡子县| 麟游县| 江油市| 临泉县| 巴林右旗| 娱乐| 霍林郭勒市| 阿巴嘎旗| 白玉县| 泸定县| 海盐县| 财经| 青海省| 成都市| 绥芬河市| 南投市| 苏尼特左旗| 常山县| 南乐县| 博罗县| 塔城市| 土默特右旗| 长沙市| 茶陵县| 辽源市| 和静县| 东平县| 宽城|