日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Mr. Kitayuta‘s Technology CodeForces - 505D(并查集+拓扑排序或dfs找环) 题解

發布時間:2023/12/10 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mr. Kitayuta‘s Technology CodeForces - 505D(并查集+拓扑排序或dfs找环) 题解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目?
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; }

?

總結

以上是生活随笔為你收集整理的Mr. Kitayuta‘s Technology CodeForces - 505D(并查集+拓扑排序或dfs找环) 题解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。