NC50772 B題(極簡)

時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 131072K,其他語言262144K
64bit IO Format: %lld

題目描述

有一個連通圖 包含 n 個點 n 條無向邊 其中每個點都與其他的兩個點直接相連 (即這是一個環)
現在這個環的邊變成了有向邊 變成了有向邊後得到的有向圖不一定是強連通的 
(強連通圖是指一個有向圖中任意兩點v1、v2間存在v1到v2的路徑及v2到v1的路徑的圖)

所以現在給出 n 條有向邊和把某條有向邊轉換方向後的代價, 問要使輸入的有向圖變成一個強連通圖
例如輸入
3
1 3 1
1 2 1
3 2 1
表示有一條有向邊 1 -> 3 如果把這條邊變成 3 -> 1 的代價是 1
表示有一條有向邊 1 -> 2 如果把這條邊變成 2 -> 1 的代價是 1
表示有一條有向邊 3 -> 2 如果把這條邊變成 2 -> 3 的代價是 1
對於輸入的這個有向圖是不存在 2 -> 3 的路徑的 所以可以把 有向邊 1 -> 2 變爲 2 -> 1 這樣圖中任意兩點均相互可達

輸入描述:

多組測試數據。

第一行給出數字n,代表頂點數量 (3 ≤ n ≤ 100)。

接下來n行給出路徑。

每行給出三個數字ai, bi, ci (1 ≤ ai, bi ≤ n, ai ≠ bi, 1 ≤ ci ≤ 100) — 代表ai指向bi。代價是ci。

輸出描述:

輸出最小代價

示例1

輸入

3
1 3 1
1 2 1
3 2 1
3
1 3 1
1 2 5
3 2 1
6
1 5 4
5 3 8
2 4 15
1 6 16
2 3 23
4 6 42

輸出

1
2
39

思路:每一個點都和其他兩個點相連,易看出這些點必然組成一個環。題目讓求的就是把這個環變成順時針所需要的代價小,還是變成逆時針所需要的代價小。

首先,利用dfs還原這個環,給環中每一個點按環中的順序編上號。然後順時針、逆時針枚舉,看那個所需代價小即可。

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N=110;

int n;
int a[N][N];
int snum[N],s;//snum存儲環中每個點的序號 
bool vis[N];

void dfs(int u)
{
	vis[u]=1;
	snum[s++]=u;
	for(int i=1;i<=n;i++)
	{
		if(!vis[i]&&(a[i][u]||a[u][i]))
			dfs(i);
	}
}

int main()
{
//	freopen("input.txt","r",stdin);
	
	while(cin>>n)
	{
		s=0;
		memset(a,0,sizeof a);
		memset(snum,0,sizeof snum);
		memset(vis,0,sizeof vis);
		for(int i=0;i<n;i++)
		{
			int x,y,e;
			cin>>x>>y>>e;
			a[x][y]=e;
		}
		dfs(1);
		snum[s]=1;
		int ans1=0,ans2=0;
		for(int i=0;i<n;i++) ans1+=a[snum[i]][snum[i+1]];
		for(int i=n;i>=1;i--) ans2+=a[snum[i]][snum[i-1]];
		cout<<min(ans1,ans2)<<endl;
	}
	
	return 0;
 } 

參考博客:https://blog.csdn.net/cyendra/article/details/8772903

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章