codeforces D.Dima and Bacteria (floyd+并查集) 好题

2023-11-10 00:58

本文主要是介绍codeforces D.Dima and Bacteria (floyd+并查集) 好题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接:Dima and Bacteria

Dima took up the biology of bacteria, as a result of his experiments, he invented ktypes of bacteria. Overall, there are n bacteria at his laboratory right now, and the number of bacteria of type i equals ci. For convenience, we will assume that all the bacteria are numbered from 1 to n. The bacteria of type ci are numbered from  to .

With the help of special equipment Dima can move energy from some bacteria into some other one. Of course, the use of such equipment is not free. Dima knows m ways to move energy from some bacteria to another one. The way with number i can be described with integers uivi and xi mean that this way allows moving energy from bacteria with number ui to bacteria with number vi or vice versa for xi dollars.

Dima's Chef (Inna) calls the type-distribution correct if there is a way (may be non-direct) to move energy from any bacteria of the particular type to any other bacteria of the same type (between any two bacteria of the same type) for zero cost.

As for correct type-distribution the cost of moving the energy depends only on the types of bacteria help Inna to determine is the type-distribution correct? If it is, print the matrix d with size k × k. Cell d[i][j] of this matrix must be equal to the minimal possible cost of energy-moving from bacteria with type i to bacteria with type j.

Input

The first line contains three integers n, m, k (1 ≤ n ≤ 105; 0 ≤ m ≤ 105; 1 ≤ k ≤ 500). The next line contains k integers c1, c2, ..., ck (1 ≤ ci ≤ n). Each of the next mlines contains three integers ui, vi, xi (1 ≤ ui, vi ≤ 105; 0 ≤ xi ≤ 104). It is guaranteed that .

Output

If Dima's type-distribution is correct, print string «Yes», and then k lines: in the i-th line print integers d[i][1], d[i][2], ..., d[i][k] (d[i][i] = 0). If there is no way to move energy from bacteria i to bacteria j appropriate d[i][j] must equal to -1. If the type-distribution isn't correct print «No».

Examples

Input

4 4 2
1 3
2 3 0
3 4 0
2 4 1
2 1 2

Output

Yes
0 2
2 0

Input

3 1 2
2 1
1 2 0

Output

Yes
0 -1
-1 0

Input

3 2 2
2 1
1 2 0
2 3 1

Output

Yes
0 1
1 0

Input

3 0 2
1 2

Output

No

 

题意:n个点,m条边,每条边是双向的,并且有权值。n个点分为k个种类,每个种类有Ci个点 
如果任意两个相同点之间转移,可以找到一条路径,该路径满足经过的边的权值和为0则输出Yes,

然后输出任意两个种类的点之间转移的最小路径。否则输出No;

分析:

两个问题:

1.第一个问题,相当于判断同类型的是否在一个集合内,并查集

2.第二个问题,数据范围不大,直接floy搞就行

细节处理较多,具体看代码把

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;const int N=1e5;
const int M=505;
int f[N],c[M],d[M][M],clas[N];
const int INF = 0x3f3f3f3f;
int n,m,q;
int getfa(int x) {return x == f[x] ? x : f[x] = getfa(f[x]);
}bool judge()
{int p=1;for(int i=1;i<=q;i++) ///利用种类的标号是连续的{int u=getfa(p);for(int j=0;j<c[i];j++){int v=getfa(p);if(u!=v) return 0;p++;}}return 1;
}
void Floyd() {for (int i = 1; i <= q; i++) d[i][i] = 0;for (int x = 1; x <= q; x++) {for (int i = 1; i <= q; i++) {for (int j = 1; j <= q; j++) {d[i][j] = min(d[i][j], d[i][x] + d[x][j]);}}}
}int main()
{scanf("%d%d%d",&n,&m,&q);int cnt=1;for(int i=1;i<=n;i++)f[i]=i;memset(d,INF,sizeof(d));for(int i=1;i<=q;i++){scanf("%d",&c[i]);for(int j=0;j<c[i];j++){clas[cnt++]=i;}}for(int i=1;i<=m;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);if(w==0){int x=getfa(u);int y=getfa(v);if(x!=y)f[y]=x;}d[clas[u]][clas[v]]=d[clas[v]][clas[u]]=min(d[clas[u]][clas[v]],w);}if(judge()){printf("Yes\n");Floyd();for(int i = 1; i <= q; i++) {for (int j = 1; j < q; j++) printf("%d ", d[i][j] != INF ? d[i][j] : -1);printf("%d\n", d[i][q] != INF ? d[i][q] : -1);}}elseprintf("No\n");return 0;
}

 

这篇关于codeforces D.Dima and Bacteria (floyd+并查集) 好题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/379474

相关文章

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

uva 10099(floyd变式)

题意: 有一个导游要带着一群旅客从一个城市到达另一个城市,每个城市之间有最大的旅客流量限制。 问最少几趟能将这些旅客从一个城市搞到另一个城市。 解析: 用floyd找出最小流量中的最大边,然后次数就是   ceil(总人数 / 最大承载量 - 1),-1的意思是导游每次也要在车上。 ps.老司机哭晕在厕所 代码: #include <iostream>#includ

uva 10048(floyd变式)

题意: 求两个点之间经过的路径中最大噪声最小的值。 解析: floyd的变式,每次取g[i][k] g[k][j]中的大边与当前边g[i][j]比较,取小。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#includ

poj 1734 (floyd求最小环并打印路径)

题意: 求图中的一个最小环,并打印路径。 解析: ans 保存最小环长度。 一直wa,最后终于找到原因,inf开太大爆掉了。。。 虽然0x3f3f3f3f用memset好用,但是还是有局限性。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#incl

poj 1182 并查集 食物链类

题意: 有n只动物,分别编号1....n。所有动物都属于A,B,C中的一种,已知A吃B,B吃C,C吃A。 按顺序给出下面两种共K条信息: 1. x 和 y 属于同一类。 2. x 吃 y 。 然而这些信息可能会出错,有可能有的信息和之前给出的信息矛盾,也有的信息可能给出的 x 和 y 不在n的范围内。 求k条信息中有多少条是不正确的。 解析: 对于每只动物,创建3个元素 i

hdu 4517 floyd+记忆化搜索

题意: 有n(100)个景点,m(1000)条路,时间限制为t(300),起点s,终点e。 访问每个景点需要时间cost_i,每个景点的访问价值为value_i。 点与点之间行走需要花费的时间为g[ i ] [ j ] 。注意点间可能有多条边。 走到一个点时可以选择访问或者不访问,并且当前点的访问价值应该严格大于前一个访问的点。 现在求,从起点出发,到达终点,在时间限制内,能得到的最大

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int