zoukankan      html  css  js  c++  java
  • UVa 12118 nspector's Dilemma (构造+DFS+欧拉回路)

    题意:给定n个点,e条边和每条边的长度t,每两个点之间都有路相连,让你求一条最短的路经过这e条边。

    析:刚开始想到要判连通,然后把相应的几块加起来,但是,第二个样例就不过,后来一想,那么有欧拉回路的还得加1啊。

    又想每次再判一次是不是欧拉回路,怎么判又是问题,因为并不知道哪些是连在一块的,还得再查找,麻烦啊。。。。

    后来上网看了一下题解,原来是要构造啊,也就是说把每个连通块都构造成一个欧拉回路,那么再减去端点的,就能完全连通了。

    真是好方法,欧拉回路满足每个点的度都是偶数,也就是说如果不是偶数那么我们就人为的给加上一条,最后计算我们加了多少条,

    然后再加上原来题目的e条,就是最后的条数。

    代码如下:

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    
    using namespace std;
    const int maxn = 1000 + 10;
    int t, n, e;
    vector<int> G[maxn];
    bool vis[maxn];
    
    int dfs(int u){
        if(vis[u])  return 0;
        vis[u] = true;
        int ans = (G[u].size() & 1);
        for(int i = 0; i < G[u].size(); ++i)
            ans += dfs(G[u][i]);
        return ans;
    }
    
    int solve(){
        int ans = 0;
        for(int i = 1; i <= n; ++i)
            if(!G[i].empty() && !vis[i])
                ans += max(dfs(i), 2);
        return max((ans-2) / 2, 0) + e;
    }
    
    int main(){
    //    freopen("in.txt", "r", stdin);
        int kase = 0;
        while(scanf("%d %d %d", &n, &e, &t) == 3){
            if(!n && !e && !t)  break;
            int u, v;
            for(int i = 1; i <= n; ++i)  G[i].clear();
            memset(vis, 0, sizeof(vis));
            for(int i = 0; i < e; ++i){
                scanf("%d %d", &u, &v);
                G[u].push_back(v);
                G[v].push_back(u);
            }
    
            printf("Case %d: %d
    ", ++kase, t * solve());
        }
        return 0;
    }
    
  • 相关阅读:
    CSS中 link 和@import 的区别是?
    display:none 和 visibility: hidden的区别
    怎样清除浮动
    纯CSS水波纹按钮效果
    如何让一个div水平垂直居中
    如何让一个div水平居中
    Vue封装简单的axios库
    Echarts-x轴数据换行显示
    Vue+Webpack打包路径问题
    Vue中Mint-ui底部弹出(上拉)组件
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5577214.html
Copyright © 2011-2022 走看看