Sicily 1915. Steal the Treasure

本文解析了一道关于盗宝联盟的算法题,题目设定在一个包含多个城市的国家中,城市间通过定向或非定向道路连接,道路上藏有宝藏。文章详细介绍了如何利用算法最大化盗宝收益,包括输入输出格式、示例及源代码。

1915. Steal the Treasure

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

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

// Problem#: 1915
// Submission#: 3591451
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

const int MAXN = 1001;
const int MAXM = MAXN * (MAXN - 1) / 2;

int x[MAXM], y[MAXM], d[MAXM], w[MAXM];
int order[MAXM];
int father[MAXN];
int r[MAXN];
int slot[MAXN];
int n, m;

bool pr(int i, int j) {return w[i] > w[j];}

int find(int p) {
    if (father[p] == 0) return p;
    return father[p] = find(father[p]);
}

void merge(int x, int y) {
    if (r[x] < r[y]) return merge(y, x);
    father[y] = x;
    slot[x] += slot[y];
    if (r[x] == r[y]) r[x]++;
}

int main() {
    while (scanf("%d%d", &n, &m) == 2) {
        for (int i = 0; i < m; i++) {
            scanf("%d%d%d%d", x + i, y + i, d + i, w + i);
            order[i] = i;
        }
        sort(order, order + m, pr);
        for (int i = 1; i <= n; i++) {
            father[i] = r[i] = 0;
            slot[i] = 1;
        }
        int ret = 0;
        for (int i = 0; i < m; i++) {
            int cur = order[i];
            if (d[cur] == 0) {
                int fx = find(x[cur]);
                int fy = find(y[cur]);
                if (slot[fx] + slot[fy] > 0) {
                    ret += w[cur];
                    slot[fx]--;
                    if (fx != fy) merge(fx, fy);
                }
            } else {
                int fx = find(x[cur]);
                if (slot[fx] > 0) {
                    ret += w[cur];
                    slot[fx]--;
                }
            }
        }
        printf("%d\n", ret);
    }
    return 0;
}                                 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值