• hdu 2480 贪心+简单并查集


    Steal the Treasure

    Time Limit: 10000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 775    Accepted Submission(s): 213

    Problem Description
    The alliance of thieves decides to steal the treasure from country A. There are n cities in country A. Cities are connected by directional or bidirectional road. To avoid the risk, the king of country A divides his treasure and hides them in some place on the road.   The alliance has found out the secret of the king. They get a map of country A which shows the location and the quantity of treasure on each road. In order to make the maximum profit and reduce the least loss, the alliance determines to send n thieves respectively to each city (one city one thief). At the appointed time, each thief chooses one road (if there is a road and notice that the road may have direction) to get to its corresponding city. Then he can steal the treasure on that road. After stealing, all the thieves return back to their base immediately.   The heads of the alliance wonder to know the quantity of the treasure they can steal at most.
     
    Input
    There are multiple cases. Input is terminated by EOF.   For each case, the first line contains two integers n (1<=n<=1000) and m (0<=m<=n*(n-1)/2), representing the number of cities and the number of roads in country A. The following m lines, each line contains four integers x, y (1<=x, y<=n, x≠y), d (0<=d<=1), w (0<=w<=1000), which means that there is a road from city x to city y, d=0 shows this road is bidirectional and d=1 shows it is directional and x the starting point, w is the quantity of treasure on the road.   We guarantee that the road (x, y) and (y, x) will never appear together in the same case.
     
    Output
    For each case, output the maximum quantity of treasure the alliance can get.
     
    Sample Input
    2 1 1 2 0 10 5 5 1 2 1 0 1 3 1 10 2 3 0 20 3 4 0 30 4 2 1 40
     
    Sample Output
    10 100
     题目大意:有n个城市,这些城市由m条道路连通,每一条道路都有着一定的权值(财富),这些道路有的是可以双向连通的,有的是单向的,只能从一个点出发,现在每一个城市都有着一个小偷,在特定时刻,这些小偷可以从这个城市前往任一条道路(如果可以),并拿走这条道路上的财富,现在问你最多能拿到多少财富。
    思路分析:首先肯定是贪心,将边按照边权从大到小排序,到底能不能拿这个路上的财富是由他的端点城市决定的,对于有向边,如果起点未被标记,那么就拿走财富,标记起点,对于无向边,如果有一个点没被标记,就标记那个点,否则就用并查集将其缩为一点。
    代码:
    #include <iostream>
    #include<cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int maxn=1000+10;
    struct node
    {
        int x,y;
        int d,w;
    };
    node edge[maxn*maxn/2];
    int fa[maxn];
    int root(int x)
    {
        return (x==fa[x])?x:fa[x]=root(fa[x]);
    }
    bool cmp(node a,node b)
    {
        return a.w>b.w;
    }
    bool vis[maxn];
    int n,m;
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            memset(vis,false,sizeof(vis));
            for(int i=1;i<=n;i++)
                fa[i]=i;
            for(int i=0;i<m;i++)
            {
                scanf("%d%d%d%d",&edge[i].x,&edge[i].y,&edge[i].d,&edge[i].w);
            }
            sort(edge,edge+m,cmp);
            int ans=0;
            for(int i=0;i<m;i++)
            {
                int fx=root(edge[i].x);
                int fy=root(edge[i].y);
                if(vis[fx]&&vis[fy]) continue;
                if(edge[i].d==1&&vis[fx]) continue;
                ans+=edge[i].w;
                if(edge[i].d==1) vis[fx]=true;
                else
                {
                    if(fx==fy) vis[fx]=true;
                    else if(vis[fx]) vis[fy]=true;
                    else if(vis[fy]) vis[fx]=true;
                    else fa[fx]=fy;//缩点
                }
            }
            printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    浏览器输入一个url到整个页面显示出来经历了哪些过程?
    ajax
    为什么JS是单线程?JS中的Event Loop(事件循环)?JS如何实现异步?setimeout?
    jQuery中ready方法的实现
    this+call、apply、bind的区别与使用
    内存泄漏、垃圾回收机制、哪些情况会导致内存泄漏
    浏览器同源策略和跨域方法
    node.js
    JS原型、原型链、构造函数、实例与继承
    JS常用操作节点的方法
  • 原文地址:https://www.cnblogs.com/xuejianye/p/5701520.html
Copyright © 2020-2023  润新知