codeforces

来源:互联网 发布:360.cn 域名价格 编辑:程序博客网 时间:2024/05/01 10:28
A -智商题
Time Limit:1000MS    Memory Limit:262144KB    64bit IO Format:%I64d & %I64u
SubmitStatusPracticeCodeForces 445C

Description

DZY loves Physics, and he enjoys calculating density.

Almost everything has density, even a graph. We define the density of a non-directed graph (nodes and edges of the graph have some values) as follows:

where v is the sum of the values of the nodes,e is the sum of the values of the edges.

Once DZY got a graph G, now he wants to find a connected induced subgraphG' of the graph, such that the density of G' is as large as possible.

An induced subgraph G'(V', E') of a graphG(V, E) is a graph that satisfies:

  • ;
  • edge if and only if, and edge;
  • the value of an edge in G' is the same as the value of the corresponding edge inG, so as the value of a node.

Help DZY to find the induced subgraph with maximum density. Note that the induced subgraph you choose must be connected.

Input

The first line contains two space-separated integersn (1 ≤ n ≤ 500), . Integern represents the number of nodes of the graphG, m represents the number of edges.

The second line contains n space-separated integersxi (1 ≤ xi ≤ 106), wherexi represents the value of thei-th node. Consider the graph nodes are numbered from1 to n.

Each of the next m lines contains three space-separated integersai, bi, ci (1 ≤ ai < bi ≤ n; 1 ≤ ci ≤ 103), denoting an edge between node ai andbi with valueci. The graph won't contain multiple edges.

Output

Output a real number denoting the answer, with an absolute or relative error of at most10 - 9.

Sample Input

Input
1 01
Output
0.000000000000000
Input
2 11 21 2 1
Output
3.000000000000000
Input
5 613 56 73 98 171 2 561 3 291 4 422 3 952 4 883 4 63
Output
2.965517241379311

题目大意:给出一张图,图中的每个节点,每条边都有一个权值,现在有从中挑出一张子图,要求子图联通,并且被选中的任意两点,如果存在边,则一定要被选中。问说点的权值和/边的权值和最大是多少。

解题思路:是图论中的一个结论,最多两个节点,所以枚举两条边就可以了。

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 500;int n, m;double val[maxn+5];int main () {    scanf("%d%d", &n, &m);    for (int i = 1; i <= n; i++)        scanf("%lf", &val[i]);    double ans = 0, k;    int a, b;    for (int i = 0; i < m; i++) {        scanf("%d%d%lf", &a, &b, &k);        double tmp = (val[a] + val[b]) / k;        if (tmp > ans)            ans = tmp;    }    printf("%.15lf\n", ans);    return 0;}

B - DFS或并查集
Time Limit:1000MS    Memory Limit:262144KB    64bit IO Format:%I64d & %I64u
SubmitStatusPracticeCodeForces 445B

Description

DZY loves chemistry, and he enjoys mixing chemicals.

DZY has n chemicals, and m pairs of them will react. He wants to pour these chemicals into a test tube, and he needs to pour them in one by one, in any order.

Let's consider the danger of a test tube. Danger of an empty test tube is 1. And every time when DZY pours a chemical, if there are already one or more chemicals in the test tube that can react with it, the danger of the test tube will be multiplied by2. Otherwise the danger remains as it is.

Find the maximum possible danger after pouring all the chemicals one by one in optimal order.

Input

The first line contains two space-separated integers n andm.

Each of the next m lines contains two space-separated integersxi andyi(1 ≤ xi < yi ≤ n). These integers mean that the chemical xi will react with the chemicalyi. Each pair of chemicals will appear at most once in the input.

Consider all the chemicals numbered from 1 to n in some order.

Output

Print a single integer — the maximum possible danger.

Sample Input

Input
1 0
Output
1
Input
2 11 2
Output
2
Input
3 21 22 3
Output
4
算法思想:并查集,将有反应关系的试剂放到一个集合,这样就形成了t个集合,每次从一个集合中选择一个试剂放入试管,会发现不会发生反应的次数就是集合数,那么n减去集合数就是最大反应的次数。

#include<iostream>#include<math.h>using namespace std;int pre[1005];int find(int x){    return x==pre[x]?x:pre[x]=find(pre[x]);//找到x的祖先但是不压缩路径}void Union(int x,int y){    int fx=find(x);    int fy=find(y);    if(fx!=fy)    {        pre[fx]=fy;    }}int main(){    int n,m,a,b;    while(cin>>n>>m)    {        int ans=0;        for(int i=1;i<=n;i++)            pre[i]=i;        if(m==0)        {            cout<<"1"<<endl;            continue;        }        for(int i=0;i<m;i++)        {            cin>>a>>b;            Union(a,b);        }        for(int i=1;i<=n;i++)        {            if(pre[i]==i)                ans++;        }        cout<<pow(2,n-ans)<<endl;    }    return 0;}


0 0