Inspector's Dilemma UVA

来源:互联网 发布:sqlserver 回滚数据 编辑:程序博客网 时间:2024/06/06 08:50

任意两点之间都有连通,要输出经过所有给出的边的最小时间

要使经过所有所给边的时间最小,一定不会将一个边走过两次,这样就变成
了构造一个欧拉道路的问题,输入也许有多个连通块,所以每个连通块都要
构造成一个欧拉道路(回路),通过度数统计需要增加的边,再加上连接不同
连通快的边,再加上所给出的边就是答案。

#include<iostream>#include<cstring>#include<vector>using namespace std;const int maxn = 1000 + 5;int G[maxn][maxn];int degree[maxn];bool done[maxn];int V, E, T;vector<int> node;int cnt, first;void DFS(int u){    done[u] = true;    node.push_back(u);    for (int i = 1; i <= V; i++)    {        if (G[u][i])        {            if (first)            //独点不计入连通块            {                cnt++;                first = 0;            }            degree[u]++;            if (!done[i])                DFS(i);        }    }}int main(){    int t = 0;    while (cin >> V >> E >> T && V)    {        memset(G,0,sizeof(G));        memset(done, 0, sizeof(done));        memset(degree, 0, sizeof(degree));        int a, b;        for (int i = 0; i < E; i++)        {            cin >> a >> b;            G[a][b] = 1;            G[b][a] = 1;        }        cnt = 0;        int ans = 0;        int temp;        for (int i = 1; i <= V; i++)            if (!done[i])            {                first = 1;                  //独点不计入连通块                temp = 0;                node.clear();                DFS(i);                //cnt++;//独点不计入连通块                for (int i = 0; i < node.size(); i++)                    if (degree[node[i]] % 2 == 1)                        temp++;                if(temp) //temp==0代表首尾相连                    ans += (temp - 2) / 2; //补边            }        if (cnt != 0)  //注意零输入            ans += (cnt - 1) + E; //连接连通块        else            ans = 0;        cout << "Case " << ++t << ": " << ans*T << endl;    }}
0 0
原创粉丝点击