zoukankan      html  css  js  c++  java
  • 一道图论神题

    一道图论神题

    Time Limit:1000ms Memory Limit:128MB

    题目描述

    LYK有一张无向图G={V,E},这张无向图有n个点m条边组成。并且这是一张带权图,只有点权。

    LYK想把这个图删干净,它的方法是这样的。每次选择一个点,将它删掉,但删这个点是需要代价的。假设与这个点相连的还没被删掉的点是u1,u2,…,uk。LYK将会增加a[u1],a[u2],…,a[uk]的疲劳值。

    它想将所有点都删掉,并且删完后自己的疲劳值之和最小。你能帮帮它吗?

    输入格式

    第一行两个数n,m表示一张n个点m条边的图。

    第二行n个数ai表示点权。

    接下来m行每行三个数u,v,表示有一条连接u,v的边。数据保证任意两个点之间最多一条边相连,并且不存在自环。

    输出格式

    你需要输出这个最小疲劳值是多少。

    输入样例

    4 3

    10 20 30 40

    1 4

    1 2

    2 3

    输出样例

    40

    样例解释

    一个合理的方法是先删4号点,此时有10点疲劳值。接下来删3号点,获得20点疲劳值,再删2号点,获得10点疲劳值,最后删1号点,没有疲劳值。总计40点疲劳值。

    对于30%的数据n<=10。

    对于60%的数据n,m<=1000。

    对于100%的数据1<=n,m,ai<=100000

    题解

    把删点转化成删边,定义一条边的边权为一对点后删的点的点权,最后每条边都是要被删掉的。

    对于每条边,肯定优先删除点权大的点。

    正确性证明:将无向图中的边按点权大的点向点权小的点连有向边,最后一定是一张DAG图。

    代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    #define LL long long
    using namespace std;
    const int N=100005;
    int n,m;
    int a[100005];
    LL ans;
    int main(){
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)scanf("%d",&a[i]);
        int u,v;
        while(m--){
            scanf("%d%d",&u,&v);
            ans+=min(a[u],a[v]);
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    spring cloud 和 阿里微服务spring cloud Alibaba
    为WPF中的ContentControl设置背景色
    java RSA 解密
    java OA系统 自定义表单 流程审批 电子印章 手写文字识别 电子签名 即时通讯
    Hystrix 配置参数全解析
    spring cloud 2020 gateway 报错503
    Spring Boot 配置 Quartz 定时任务
    Mybatis 整合 ehcache缓存
    Springboot 整合阿里数据库连接池 druid
    java OA系统 自定义表单 流程审批 电子印章 手写文字识别 电子签名 即时通讯
  • 原文地址:https://www.cnblogs.com/chezhongyang/p/7647929.html
Copyright © 2011-2022 走看看