HDU 5422:Rikka with Graph

Rikka with Graph

 
 Accepts: 353
 
 Submissions: 1174
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:

勇太有一张nn个点mm条边的无向图,每一条边的长度都是1。现在他想再在这张图上连上一条连接两个不同顶点边,使得1号点到nn号点的最短路尽可能的短。现在他想要知道最短路最短是多少,以及再保证最短路最短的情况下,他有多少种连边的方案。

当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
输入描述
数据组数不超过100组。每组数据的第一行两个整数n,m(2 \leq n \leq 100, 0 \leq m \leq 100)n,m(2n100,0m100)。

接下来mm行。每行两个整数u,v(1 \leq u,v \leq n)u,v(1u,vn),代表原图中的一条无向边。注意可能有自环和重边。
输出描述
对于每一组数据输出一行两个整数:最短路最短是多少以及加边的方案数。
输入样例
2 1
1 2
输出样例
1 1
Hint
你只能连上1 2这条边。

一开始看以为BC周赛第一道题竟然是图论的内容,中间自己的思路一度跑偏, Dijkstra的想法都想上了。

最后发现根本不是那么回事,自己跑偏了。

既然可以随意连,包括重边,那1到n的最短路径一定是1啊。

如果1和n原来没有边,连上就是1。

如果1和n原来有边,最短路径就还是1,边就随意连,还可以有重边,那就是C(n,2),也就是n*(n-1)/2。

代码:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std;

int edge[105][105];
int c[105][105];

void init()
{
    int i, j;
    memset(c, 0, sizeof(c));

    for (i = 0; i <= 104; i++)
    {
        for (j = 0; j <= i; j++)
        {
            if (j == 0 || j == i)
                c[i][j] = 1;
            else
                c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
        }
    }
}

int main()
{
    int i, n, m, temp1, temp2,edge_num;
    init();

    while (scanf("%d%d", &n, &m)!=EOF)
    {
        memset(edge, 0, sizeof(edge));
        edge_num = m;

        for (i = 1; i <= m; i++)
        {
            scanf("%d%d", &temp1, &temp2);

            edge[temp1][temp2] = 1;
            edge[temp2][temp1] = 1;
        }
        if (edge[1][n] == 0)
            cout << 1 << " " << 1 << endl;
        else
            cout << 1 << " " << c[n][2] << endl;
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

posted on 2015-08-29 22:13  光速小子  阅读(133)  评论(0编辑  收藏  举报

导航