HNU13247Connected Caves (拓扑)

Connected Caves
Time Limit: 2000ms, Special Time Limit:5000ms,
Memory Limit:65536KB
Total submit users: 6, Accepted users:
5
Problem 13247 : Special judge
Problem description

You’re an intern at Greedy Cave Plundering Corporation. Your new job is to help with one of GCPC’s projects: extracting valuable gemstones from a network of connected caves. The history of the project so far:

? Tom, one of the project managers, has hired Jill, a gemstone expert. She has already surveyed these caves and determined the value of all gemstones in each cave.

? Ruby, another project manager (PM), has been busy “guesstimating” a time frame, the budget and possible profits for this project.

? Evelyn and Jerry (also PMs) have hired two cave diggers and instructed them to extract the gemstones.

? The cave diggers needed equipment to extract the gemstones and transport them to the surface. So Jimmy (another PM) ordered some machines. Sadly, he did not communicate well with the cave diggers - he bought machines that are way too big for the current passage
ways between caves.

? To fix this, Jimmy was fired and James, his successor, has ordered a very big drilling machine, so the cave diggers can widen the passage ways. However, James was fearful of cutting into his salary bonus, so he bought the cheapest machine he could find. Soon,
after widening the passage way from the surface into cave 1, the cave diggers found out that the new drilling machine is very heavy and not so powerful, so it can only be used to widen a passage way that goes downwards. Once it has reached a lower cave, it
can not be carried back up because of its weight.

? This is when Alice, the project manager in charge of budget planning, announced she would ignore further requests for more equipment.

? In an eight hour meeting discussing the problems of the project, it was decided to limit the project expenses. So, if further drilling would hurt profits or if the drilling machine reaches a cave where it can not go on, it will just be abandoned. Using the
other machines, the cave diggers will then be able to harvest at least some of the gemstones. Afterwards, the dig site will probably be sold to another company. Ruby is already thinking about hiring her brother as a sales expert...

This is where you come in. Tom has hired you to determine which passage ways should be widened and thereby which caves should be visited to maximize profits. Widening a passage way requires energy, materials and so on. You have to consider these costs. You
will be given a map of all caves and passage ways. The map was created by the cave diggers, so it should be accurate. It contains only passage ways the drilling machine can handle, including the correct drilling direction. All caves in the map are reachable
from cave one.

Input

The input starts with a line containing T, the number of test cases (1 ≤ T ≤ 10). Each test case starts with a line containing two integers: N, the number of caves, and E, the number of passage ways (1 ≤ N ≤ 2 · 10^4; 0 ≤ E ≤ 10^5). The second line contains
N integers v1 v2... vN. videscribes the value of all gemstones in cave i (0 ≤ vi≤ 10^4). Each of the next E lines contains three integers: a
e b e c e . Such a line represents one of the possible direct passage ways from cave a
e to cave b e , widening this passage way will cost c
e
(1 ≤ a e ,b e ≤ N; 0 ≤ c e ≤ 10^4). It is guaranteed that the input contains only valid digging directions, i.e. cave b
e will be strictly deeper than a e . You always start from cave number 1, because the digging machine is already there and there are no caves above.

Output

Output two lines for every test case. In the first line print two integers P and C, where P is the profit of the best possible route from top to bottom and C is the number of visited caves on that path. In the second line print the IDs of those caves, ordered
from top to bottom. If there are multiple solutions with optimal profit, print any.

Sample Input
3
1 0
10
4 3
10 20 30 40
1 2 19
1 3 23
1 4 34
4 4
10 20 30 40
1 2 10
2 4 20
1 3 20
3 4 10
Sample Output
10 1
1
17 2
1 3
50 3
1 3 4
Problem Source
GCPC 2014

题意:给出n个点1~n,m条边,每个点有一个价值,给出的每条边是有向边a-->b 花费c,无环图,得到的总价值= 走过的点的价值和-走过边的花费。从点1开始走,问最大能得多少价值。有多少个点,都有哪些点组成。

解题:就用拓扑序列做。须自写scanf函数,否则超时。

#include<stdio.h>
#include<vector>
using namespace std;

#define LL int
const int N = 20005;
#define inf -600000000

struct TO
{
    int v;
    LL c;
};
LL node[N],valu[N];
int fath[N],n,in[N];
vector<TO>tmap[N];
void init()
{
    for(int i=1; i<=n;i++)
    {
        in[i]=0; node[i]=inf; tmap[i].clear();
    }
}
void topu()
{
    int k,to[N],id;
    LL sum;
    k=0;
    for(int i=2;i<=n;i++)
        if(!in[i])
            to[++k]=i;
    while(k)
    {
        int s=to[k]; k--;
        for(int i=0;i<tmap[s].size();i++)
        {
            int v=tmap[s][i].v;
            in[v]--;
            if(in[v]==0)
                to[++k]=v;
        }
    }
    to[++k]=1;
    node[1]=valu[1]; fath[1]=1;
    sum=node[1],id=1;
    while(k)
    {
        int s=to[k]; k--;
        for(int i=0;i<tmap[s].size();i++)
        {
            int v=tmap[s][i].v;
            in[v]--;
            if(in[v]==0)
                to[++k]=v;
            if(node[v]<node[s]+valu[v]-tmap[s][i].c)
                node[v]=node[s]+valu[v]-tmap[s][i].c,fath[v]=s;
            if(sum<node[v])
                sum=node[v],id=v;
        }
    }
    k=0;
    while(fath[id]!=id)
    {
        to[++k]=id; id=fath[id];
    }
    to[++k]=id;
    printf("%d %d\n%d",sum,k,to[k]);
    for(int i=k-1; i>0; i--)
        printf(" %d",to[i]);
    printf("\n");
}
inline void scanf(int &a)
{
    int flag=0;
    char ch;
    while(ch=getchar())
    {
        if(ch=='-')
        {
            flag=1; break;
        }
        if(ch>='0'&&ch<='9')
            break;
    }
    a=0;
    if(flag==0)
        a=ch-'0';
    while(ch=getchar())
    {
        if(ch<'0'||ch>'9')
            break;
        a=a*10+ch-'0';
    }
    if(flag)
        a=-a;
}
int main()
{
    int t,m,a,b,c;
    scanf(t);
    while(t--)
    {
        scanf(n);
        scanf(m);
        init();

        for(int i=1;i<=n;i++)
            scanf(valu[i]);
        TO ss;
        while(m--)
        {
            scanf(a); scanf(ss.v); scanf(ss.c);
            if(a==ss.v)
                continue;

            tmap[a].push_back(ss);
            in[ss.v]++;
        }
        topu();
    }
}
时间: 2024-10-05 07:37:42

HNU13247Connected Caves (拓扑)的相关文章

hdu5222 拓扑+并查集

http://acm.hdu.edu.cn/showproblem.php?pid=5222 Problem Description Miceren likes exploration and he found a huge labyrinth underground! This labyrinth has N caves and some tunnels connecting some pairs of caves. There are two types of tunnel, one typ

HDU 5222 ——Exploration——————【并查集+拓扑排序判有向环】

Exploration Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 194    Accepted Submission(s): 63 Problem Description Miceren likes exploration and he found a huge labyrinth underground! This la

拓扑排序讲解

在这里我们要说的拓扑排序是有前提的 我们在这里说的拓扑排序是基于有向无环图的!!!. (⊙o⊙)…我所说的有向无环图都知道是什么东西吧.. 如果不知道,我们下面先来来说说什么是有向无环图. 所谓有向无环图,顾名思义是不存在环的有向图(至于有向图是什么不知道的在前面我们有一个图论讲解上都有). 点的入度:以这个点为结束点的边数. 点的出度:以这个点为出发点的边的条数. 拓扑序就是对于一个节点的一个排列,使得(u,v)属于E,那么u一定出现在v的前面.然而拓扑排序就是一个用来求拓扑序的东西. 对于左

CSU 1804: 有向无环图(拓扑排序)

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1804 题意:…… 思路:对于某条路径,在遍历到某个点的时候,之前遍历过的点都可以到达它,因此在这个时候对答案的贡献就是∑(a1 + a2 + a3 + ... + ai) * bv,其中a是之前遍历到的点,v是当前遍历的点. 这样想之后就很简单了.类似于前缀和,每次遍历到一个v点,就把a[u]加给a[v],然后像平时的拓扑排序做就行了. 1 #include <bits/stdc++.h>

AE创建拓扑

转自原文 AE创建拓扑 /// <summary> /// 创建拓朴 /// </summary> /// <param name="featureWorkspace">要素集工作空间</param> /// <param name="featuredatasetName"></param> /// <param name="featureClassName">&

7-9-有向图无环拓扑排序-图-第7章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第7章  图 - 有向无环图拓扑排序 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? Status.h.SequenceStack.c.ALGraph.c    

hihoCoder 1175:拓扑排序二

题目链接: http://hihocoder.com/problemset/problem/1175 题目难度:一星级(简单题) 今天闲来无事,决定刷一道水题.结果发现这道水题居然把我卡了将近一个钟头. 最后终于调通了.总结起来,原因只有一个:不够仔细. 思路不用细说了,就是拓扑排序的简单应用.然而,一些不起眼的细节才是让你掉坑里的真正原因. 猜猜哪儿可能出bug? // A simple problem, but you can't be too careful with it. #inclu

hdu1285(拓扑排序)

这道题要求没有输赢关系的两个元素必须按照升序输出,有输赢关系的,赢得在输的前面,所以用队列或者栈来降低时间复杂度的优化过的拓扑排序会出错. 比如这组输入 5 3 1 2 2 3 4 5 至少我写的两种拓扑排序都wa了.但是不用队列或者栈来优化的话, 1.每次都从头至尾扫描一遍,找到一个没标记过的节点, 2.将它标记 3.然后删除从它出来的每条边. 重复这三个操作,加标记的次序,就是题目要的答案. 下面的代码中用到了队列,但只是用来保存答案而已.并没有用它优化的意思. #include <iost

uva 10305 Ordering Tasks(拓扑排序)

拓扑排序,不用判断是否有环,dfs挺简单的 代码: #include<stdio.h> #include<string.h> #include<stdlib.h> int map[105][105]; int visit[105]; int c[105]; int n,m,t; void dfs(int x) { visit[x] = 1; for(int i=1; i<=n; i++) { if(!visit[i]&&map[i][x]==1)