codeforces Dima and Bacteria

题意:给出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,如果正确的话,给出两两细菌(种类)间移动能量的最小值。

思路:并差集+floyd;

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #define maxn 100010
  5 using namespace std;
  6 const int inf=1<<29;
  7
  8 int n,m,k;
  9 int g[600][600];
 10 int c[maxn];
 11 int f[maxn],u[maxn],v[maxn],x[maxn];
 12 int num[maxn];
 13 int xx[maxn];
 14 int sum[maxn];
 15
 16 int Find(int x)
 17 {
 18     if(x==f[x]) return x;
 19     return f[x]=Find(f[x]);
 20 }
 21
 22
 23 int main()
 24 {
 25      while(scanf("%d%d%d",&n,&m,&k)!=EOF)
 26      {
 27          int fx,fy;
 28         for(int i=1; i<=k; i++)
 29         {
 30             scanf("%d",&c[i]);
 31             sum[i]=sum[i-1]+c[i];
 32         }
 33         for(int i=1; i<=n; i++)
 34         {
 35             f[i]=i;
 36         }
 37         for(int i=1; i<=k; i++)
 38         {
 39             for(int j=sum[i-1]+1; j<=sum[i]; j++)
 40             {
 41                 xx[j]=i;
 42             }
 43         }
 44         for(int i=1; i<=m; i++)
 45         {
 46             scanf("%d%d%d",&u[i],&v[i],&x[i]);
 47             int uu=u[i],vv=v[i];
 48             if(uu>vv) swap(uu,vv);
 49             fx=Find(uu);
 50             fy=Find(vv);
 51             if(x[i]==0)
 52             {
 53                 if(fx!=fy)
 54                 {
 55                     f[fy]=fx;
 56                 }
 57             }
 58         }
 59         bool flag=false;
 60         for(int i=1; i<=k; i++)
 61         {
 62             int x=Find(sum[i-1]+1);
 63             int cnt=0;
 64             for(int j=sum[i-1]+1; j<=sum[i]; j++)
 65             {
 66                 if(Find(j)==x) cnt++;
 67             }
 68             if(cnt!=c[i])
 69             {
 70                 flag=true;
 71                 break;
 72             }
 73         }
 74         if(flag)
 75         {
 76             printf("No\n");
 77         }
 78         else
 79         {
 80             for(int i=1; i<=k; i++)
 81             {
 82                 for(int j=1; j<=k; j++)
 83                 {
 84                     if(i==j) g[i][j]=0;
 85                     else g[i][j]=inf;
 86                 }
 87             }
 88             for(int i=1; i<=m; i++)
 89             {
 90                 g[xx[u[i]]][xx[v[i]]]=min(g[xx[u[i]]][xx[v[i]]],x[i]);
 91                 g[xx[v[i]]][xx[u[i]]]=min(g[xx[v[i]]][xx[u[i]]],x[i]);
 92             }
 93             for(int c=1; c<=k; c++)
 94             {
 95                 for(int i=1; i<=k; i++)
 96                 {
 97                     if(i==c)continue;
 98                     for(int j=1; j<=k; j++)
 99                     {
100                        if(i==j||j==c) continue;
101                        g[i][j]=min(g[i][j],g[i][c]+g[c][j]);
102                     }
103                 }
104             }
105             printf("Yes\n");
106             for(int i=1; i<=k; i++)
107             {
108                 for(int j=1; j<=k; j++)
109                 {
110                     if(g[i][j]==inf&&i!=j)
111                     {
112                         printf("-1 ");
113                     }
114                     else printf("%d ",g[i][j]);
115                 }
116                 printf("\n");
117             }
118         }
119      }
120      return 0;
121 }

时间: 2024-11-09 02:51:39

codeforces Dima and Bacteria的相关文章

CodeForces 400D (最短路+并查集) Dima and Bacteria

 Description Dima took up the biology of bacteria, as a result of his experiments, he invented k types 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

codeforces 400 D Dima and Bacteria【并查集 Floyd】

题意:给出n个点,分别属于k个集合,判断每个集合里面的点的距离都为0,为0的话输出yes,并输出任意两个集合之间的最短路 这道题目有两个地方不会处理, 先是n个点,分别属于k个集合,该怎么记录下来这里, 然后就是判断每个集合里面的点的距离是否为1,这里可以用并查集来做,如果在输入点的时候,距离为0,就将这两点合并 最后判断每个点,如果他们同属于一个集合,判断它俩的根是否一样就可以了 最后用floyd求最短路 1 #include<iostream> 2 #include<cstdio&g

codeforces 579A Raising Bacteria

A. Raising Bacteria You are a lover of bacteria. You want to raise some bacteria in a box. Initially, the box is empty. Each morning, you can put any number of bacteria into the box. And each night, every bacterium in the box will split into two bact

Codeforces Round#320 Div2 解题报告

Codeforces Round#320 Div2 先做个标题党,骗骗访问量,结束后再来写咯. codeforces 579A Raising Bacteria codeforces 579B Finding Team Member codeforces 579C A Problem about Polyline codeforces 579D "Or" Game codeforces 579E Weakness and Poorness codeforces 579F LCS Aga

SDKD 2017 Summer Single Training #03

今天的题目有 6 个. 第一题: CodeForces - 400D  Dima and Bacteria 这个题实际是不难的,难的可能在题意的理解上还有题干有点长,这个题很考察题意上面,知识点很熟悉,并查集和Floyd. 具体题解地址:http://www.cnblogs.com/dwtfukgv/p/7126059.html 第二题:CodeForces - 384E  Propagating tree 这个题确实是有难度的,当然主要是在时间上面,其实这个我是防AK的,然后这个题很容易理解,

Codeforces Round #262 (Div. 2) 460B. Little Dima and Equation(枚举)

题目链接:http://codeforces.com/problemset/problem/460/B B. Little Dima and Equation time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Little Dima misbehaved during a math lesson a lot and the nas

CodeForces 584D Dima and Lisa

1e9 以内的判断一个数是否是素数,可以直接朴素的暴力. 这倒题除了考虑1e9以内的素数的判断,还有一个歌德巴赫猜想:任意一个奇数都可一分解为三个素数的和. 第三个结论:素数是密集的,1e9以内,相邻的素数之间的间隔不会大于300,所以直接枚举也不会浪费掉太多的时间. 这里还有一点需要注意的是:朴素的判断是否是素数,i<=saqrt(n).今天的天梯赛由于记错了这个条件,导致没有求出素数,一道二十分的题没有做,好伤心. Dima and Lisa Time Limit:1000MS     Me

codeforces Sereja and Dima 题解

Sereja and Dima play a game. The rules of the game are very simple. The players have n cards in a row. Each card contains a number, all numbers on the cards are distinct. The players take turns, Sereja moves first. During his turn a player can take o

Dima and Magic Guitar CodeForces - 366E

Dima and Magic Guitar CodeForces - 366E 题意: http://blog.csdn.net/u011026968/article/details/38716425http://vawait.com/2013/11/codeforces-366e/http://www.cnblogs.com/jianglangcaijin/archive/2013/11/25/3441319.html 对于s中任意相邻两个数x和y,都要求在矩形中找出任意两个分别等于x和y的点