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;
    }
  • 相关阅读:
    5.Makefile的原理及应用
    8.adr与ldr伪指令的区别
    6.反汇编的原理
    9.S5PV210的时钟系统
    1.No MBR错误
    4.交叉编译工具链的安装及使用
    Java角度制向弧度制转化
    Java小题,通过JNI调用本地C++共享库中的对应方法实现杨辉三角的绘制
    编译安装-PHP
    编译安装-MySQL5.5
  • 原文地址:https://www.cnblogs.com/chezhongyang/p/7647929.html
Copyright © 2011-2022 走看看