1. 程式人生 > >Codeforces 400D Dima and Bacteria(Floyd+並查集)

Codeforces 400D Dima and Bacteria(Floyd+並查集)

題目大意:給出n,m和k,表示有n個細菌,m種儀器和k種細菌,給出k種細菌的數量ci,然後每個細菌按照種類排成一排(所以有第i種細菌的序號從∑(1≤j≤i-1)cj + 1 到∑(1≤j≤i)cj);接下來給出m種儀器,有u,v,x三個值,表示說從可以在第u,v號細菌之間移動能量,代價為x。請幫助博士判斷說這些細菌是否正確,正確的前提條件是說同種細菌之間移動能量為0,如果正確的話,給出兩兩細菌(種類)間移動能量的最小值。

解題思路:題目有點長,琢磨了很久,要注意的是當前細菌可以先移動到其它細菌上。我的做法是,如果當前儀器x為0,就將兩個序號的細菌連線連線(並查集),然後在判斷是否正確的時候,只要同一種細菌處於同以集合即可。然後處理最短路徑就用Floyd演算法。

#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;
const int N = 1e5+5;
const int K = 505;
const int INF = 0x3f3f3f3f;

int n, m, k, t[N], f[N];
int c[K], d[K][K];

int getfar(int x) {
	return x == f[x] ? x : f[x] = getfar(f[x]);
}

void init () {
	scanf("%d%d%d", &n, &m, &k);
	memset(d, INF, sizeof(d));
	for (int i = 1; i <= n; i++) f[i] = i;

	int p = 1, u, v, x;
	for (int i = 1; i <= k; i++) {
		scanf("%d", &c[i]);
		for (int j = 0; j < c[i]; j++) t[p++] = i;
	}

	for (int i = 0; i < m; i++) {
		scanf("%d%d%d", &u, &v, &x);

		int ui, vi;
		if (x == 0) {
			ui = getfar(u);
			vi = getfar(v);
			if (ui != vi) f[vi] = ui;
		}

		ui = t[u]; vi = t[v];
		d[ui][vi] = d[vi][ui] = min(d[ui][vi], x);
	}
}

bool judge () {

	int p = 1;
	for (int i = 1; i <= k; i++) {
		int u = getfar(p);
		for (int j = 0; j < c[i]; j++) {
			int v = getfar(p);
			if (v != u) return false;
			p++;
		}
	}
	return true;
}

void solve () {
	for (int i = 1; i <= k; i++) d[i][i] = 0;

	for (int x = 1; x <= k; x++) {
		for (int i = 1; i <= k; i++) {
			for (int j = 1; j <= k; j++) {
				d[i][j] = min(d[i][j], d[i][x] + d[x][j]);
			}
		}
	}
}

int main () {
	init ();
	if (judge()) {
		solve ();
		printf("Yes\n");
		for (int i = 1; i <= k; i++) {
			for (int j = 1; j < k; j++) printf("%d ", d[i][j] != INF ? d[i][j] : -1);
			printf("%d\n", d[i][k] != INF ? d[i][k] : -1);
		}
	} else
		printf("No\n");
	return 0;
}


相關推薦

Codeforces 400D Dima and Bacteria(Floyd+

題目大意:給出n,m和k,表示有n個細菌,m種儀器和k種細菌,給出k種細菌的數量ci,然後每個細菌按照種類排成一排(所以有第i種細菌的序號從∑(1≤j≤i-1)cj + 1 到∑(1≤j≤i)cj

Codeforces 1131F Asya And Kittens 【

依次 bsp blank 開始 tar %d n) div get <題目鏈接> 題目大意:有$1~n$只小貓,開始將它們放在指定的n個單元格內,然後隨機從n-1個隔板中拆除隔板,最終使得這些小貓在同一單元格。現在依次給出拆除隔板的順序,比如:1 4 就表示1

CodeForces 445B. DZY Loves Chemistry(

word other res 技術分享 increase ted weight hit next 轉載請註明出處:http://blog.csdn.net/u012860063?viewmode=contents 題目鏈接:http://codeforces.co

CodeForces 731C-Socks(聯通圖

C. Socks time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output Arseniy is

codeforces#766 D. Mahmoud and a Dictionary (

namespace define scanf 對應關系 force sha ict codeforce sharp 題意:給出n個單詞,m條關系,q個詢問,每個對應關系有,a和b是同義詞,a和b是反義詞,如果對應關系無法成立就輸出no,並且忽視這個關系,如果可以成立則加入這

codeforces#766 D. Mahmoud and a Dictionary (

題意:給出n個單詞,m條關係,q個詢問,每個對應關係有,a和b是同義詞,a和b是反義詞,如果對應關係無法成立就輸出no,並且忽視這個關係,如果可以成立則加入這個約束,並且輸出yes。每次詢問兩個單詞的關係,1,同義詞,2,反義詞,3,不確定 題解:這題思路比較奇特,開闢2*n的並查集的空間,第i+n代表i的

Codeforces 325 D-Reclamation

name clam .cn 每次 .html con ret ring true 借用 鏈接 的題意和解法分析的圖片。 對於這種環的形式,先用常用的手段復制一份在右邊。每次加點的過程只要看加完之後能不能通過已有的格子聯通,如果聯通則顯然已經形成了一個環。這裏判斷聯通我

Codeforces 455C Civilization 樹的直徑+

targe 路徑 ++ begin post data 操作 scanf con 題目鏈接:點擊打開鏈接 題意: 給定n個點 m條無向邊的圖 k個詢問 無重邊、自環、環 定義 2個點屬於同國家:當這兩個點連通時即這兩個點是屬於一個國家 操作1 x:輸出x所在的國家內的最

hdu5652:India and China Origins(

and std map printf etc scanf 16px 兩個 for   倒序操作用並查集判斷是否連通,新技能get√(其實以前就會了   這題細節很多。。。搞得整個程序都是調試輸出,幾度看不下去想要重寫   並查集到現在大概掌握了兩個基本用途:判斷是否連通 /

CodeForces 776D The Door Problem【

merge cnblogs 表示 turn pro name 所有 force mes CodeForces 776D The Door Problem【並查集】並查集 設 f 1--m 表示 開的情況 m+1--2*m 表示關的情況 對於每盞燈 如果他 是關

CodeForces 745C Hongcow Builds A Nation

pre its scan 思路 max 城市 define tor 博客 題意: 給了你n個城市 m條邊 k個政府 每個政府管轄的區域內不能和其他政府的區域有相連 即政府之間不存在路徑 問你在維護這種關系的同時 最多再加多少條邊 思路: 先找出來每個聯通

Codeforces 506D Mr. Kitayuta's Colorful Graph(分塊 +

pair 重新 emp %d 操作 its -- 是否 細節問題 題目鏈接 Mr. Kitayuta‘s Colorful Graph 把每種顏色分開來考慮。 所有的顏色分為兩種:涉及的點的個數 $> \sqrt{n}$ 涉及的點的個數 $<= \s

Codeforces 915F Imbalance Value of a Tree(

路徑 second long long air bit force 題意 for href 題目鏈接 Imbalance Value of a Tree 題意 給定一棵樹。求樹上所有簡單路徑中的最大權值與最小權值的差值的和。 首先考慮求所有簡單路徑中的最大權值

Codeforces 28B. pSort (

from fin section nal otherwise out esc hab game One day n cells of some array decided to play the following game. Initially each cell con

【CF659F】Polycarp and Hay(,bfs

jar 上下 等於 b+ ios str %d class style 題意: 構造一個矩陣,使得: 矩陣所有格子中數字都小於等於原矩陣,並且至少有一個元素和原矩陣相等, 構造的矩陣除了0以外的數字必須聯通並且相等,矩陣中元素之和為K。 n,m<=1e3,1<=

CodeForces - 278C 】Learning Languages(,思維

題幹: The "BerCorp" company has got n employees. These employees can use m approved official languages for the formal correspond

HDU3081:Marriage Match II (Floyd/+二分圖匹配/最大流(+二分)

Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5469 &n

Codeforces Round 722C:Destroying Array(,好題)

You are given an array consisting of n non-negative integers a1, a2, ..., an. You are going to destroy integers in the array one by one. Thus, you are g

codeforces 827D(kruskal+倍增+

傳送門 題解:先求出最小生成樹,用倍增LCA求出不在最小生成樹中的邊的答案,同時再用這個答案它去更新最小生成樹中的邊的答案。為了提高更新這一操作的效率,列舉有序(從小到大)的邊集,更新過的用並查集連在一起(由於從小到大,小的最優,下條邊一定不會再次更新它們

Codeforces 827D Best Edge Weight (最小生成樹 + 樹鏈剖分/倍增/

Codeforces 827D Best Edge Weight 題意: 給你N個點M條邊的帶邊權無向聯通圖,現在對於每條邊,問這條邊的權值最大可以是多 少,使得這條邊在該無向圖的所有最最小成樹中? 資料範圍 2 ≤N ≤ 2*1055, N -