Ural 1741 Communication Fiend(隐式图+虚拟节点最短路)

1741. Communication Fiend

Time limit: 1.0 second
Memory limit: 64 MB

Kolya has returned from a summer camp and now he‘s a real communication fiend. He spends all his free time on the Web chatting with his friends via ICQ. However, lately the protocol of this service was changed once again, and Kolya‘s client stopped working. Now, in order to communicate with his friends again, Kolya has to upgrade his client from version 1 to version n.

Kolya has found m upgrade programs on the Web. The i-th program upgrades the client from version xi to version yi and its size is di megabytes. Each program can be installed on the corresponding version of the client only; it can‘t be installed on either earlier or later versions.

The first version, which is currently installed on Kolya‘s computer, is licensed, and many of the upgrade programs are pirate copies. If a pirate upgrade program is used, the client will always be pirated after that, whatever upgrade is used later. Some of the licensed upgrade programs can be installed on a pirate version of the client, and some of them can‘t. All the pirate upgrade programs can be installed on both licensed and pirate versions of the client.

Kolya is missing his friends very much, so he wants to download the necessary upgrade programs as soon as possible. Unfortunately, his Web connection is not very fast. Help Kolya determine the minimal total traffic volume necessary for upgrading the client from version 1 to version n. Kolya doesn‘t care if the final version n of his client is licensed or not.

Input

The first line contains space-separated integers n and m (2 ≤ n ≤ 104; 1 ≤ m ≤ 104).

Each of the following m lines describes one upgrade program in the form “xi yi di si”. Here, si is the type of the program: “Pirated”, “Cracked”, or “Licensed”. A cracked upgrade program is a licensed program that can be installed on a pirate version of the client, and a licensed program can‘t be installed on a pirate version. The numbers xi and yi mean that the program is installed on version xi of the client and upgrades it to version yi. The number di is the size of the program in megabytes (1 ≤ xi < yi ≤ n; 1 ≤ di ≤ 106). The data in each line are separated with exactly one space.

Output

If Kolya can upgrade the client from version 1 to version n, output “Online” in the first line and the minimal necessary total incoming traffic volume in the second line.

If it is impossible to upgrade the client, output “Offline”.

Samples

input output
3 4
1 3 10 Licensed
1 2 2 Pirated
2 3 3 Licensed
2 3 6 Cracked
Online
8
3 1
1 2 10 Licensed
Offline

Problem Author: Alex Samsonov (prepared by Marina Mukhacheva)
Problem Source: XIV Open USU Championship

Tags: dynamic programming  (
hide tags for unsolved problems

)

Difficulty: 280    Printable version    Submit solution    Discussion (14)
My submissions    All submissions (5638)    All accepted submissions (1273)   Solutions rating (905)

题目链接:Ural 1741

题目虽说正规解法是DP,但是似乎是可以用最短路来做的,一开始想用d[i][k]表示到达i时系统状态是k然后建图进行spfa,然而最好还是WA10。

题目中间的版本变化似乎没有讲清楚,就是说用了某个升级包之后会使得当前系统的正版状态发生变化,尤其是Cracked包,用之后的状态跟用之前的状态是保持一致的,虽然题目中说它也是一个Licensed,但是不能使得盗版变成正版。

然后想了另外一种思路才A掉

可以将正版的系统节点看成1~n,盗版就是n+1~n+n,然后显然有:对于Lisenced版本只能从正版升级到正版,只能添加一条u->v的单向边;对于Pirate版本可以从正版升级到盗版也可以从盗版继续升级到盗版,因此添加u->v+n,与u+n->v+n;对于Cracked版本就是看成一种桥,盗版可以继续盗版,正版继续正版,

即u->v与u+n->v+n,然后跑一个spfa,看d[n]正版和d[n<<1]盗版的值就行了

提供一组数据用来说明Cracked的作用

4 3
1 2 1 P
2 3 3 C
3 4 6 L

答案应为 Offline

代码:

#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<long long,int> pli;
typedef long long LL;
const double PI=acos(-1.0);

const int N=2e4+10;
struct edge
{
    int to;
    int pre;
    LL w;
};
edge E[N];
int head[N],tot;
LL d[N];

void add(int s,int t,LL w)
{
    E[tot].to=t;
    E[tot].w=w;
    E[tot].pre=head[s];
    head[s]=tot++;
}
void init()
{
    CLR(d,INF);
    CLR(head,-1);
    tot=0;
}
void spfa(int s)
{
    priority_queue<pli>Q;
    d[s]=0LL;
    Q.push(pli(-d[s],s));
    while (!Q.empty())
    {
        int now=Q.top().second;
        Q.pop();
        for (int i=head[now]; ~i; i=E[i].pre)
        {
            int v=E[i].to;
            LL w=E[i].w;
            if(d[v]>d[now]+w)
            {
                d[v]=d[now]+w;
                Q.push(pli(-d[v],v));
            }
        }
    }
}

int main(void)
{
    int n,m,i,u,v;
    LL D;
    char flag[15];
    while (cin>>n>>m)
    {
        init();
        LL inf=d[0];
        for (i=0; i<m; ++i)
        {
            cin>>u>>v>>D>>flag;
            if(flag[0]==‘C‘)
            {
                add(u,v,D);
                add(n+u,n+v,D);
            }
            else if(flag[0]==‘L‘)
            {
                add(u,v,D);
            }
            else if(flag[0]==‘P‘)
            {
                add(u,n+v,D);
                add(n+u,n+v,D);
            }
        }
        spfa(1);
        LL ans=min<LL>(d[n],d[n<<1]);
        if(ans==inf)
        	cout<<"Offline"<<endl;
       	else
        	cout<<"Online"<<endl<<ans<<endl;
    }
    return 0;
}
时间: 2024-10-25 14:54:25

Ural 1741 Communication Fiend(隐式图+虚拟节点最短路)的相关文章

DP/最短路 URAL 1741 Communication Fiend

题目传送门 1 /* 2 题意:程序从1到n版本升级,正版+正版->正版,正版+盗版->盗版,盗版+盗版->盗版 3 正版+破解版->正版,盗版+破解版->盗版 4 DP:每种情况考虑一遍,递推就行了 5 注意:开long long 6 */ 7 #include <cstdio> 8 #include <iostream> 9 #include <algorithm> 10 #include <cstring> 11 #inc

八数码问题+路径寻找问题+bfs(隐式图的判重操作)

Δ路径寻找问题可以归结为隐式图的遍历,它的任务是找到一条凑够初始状态到终止问题的最优路径, 而不是像回溯法那样找到一个符合某些要求的解. 八数码问题就是路径查找问题背景下的经典训练题目. 程序框架 process()  初始化vis数组,初始化初始节点到目标节点的移动距离 dfs()搜索到每一个节点,如果不是目标节点,对其依次扩展所有子节点,并判重,全部子节点搜索完全后,改变父节点:如果是目标节点成功返回 输出最少移动步数 input: 2 6 4 1 3 7 0 5 8 8 1 5 7 3 6

隐式图的遍历

好久不看都快忘了... 一些奇怪的问题可以归为隐式图的遍历 NEUOJ544 Problem Description there is an old saying,"You can not do anything without water"or"Water is the source of life". Besides, human beings are made of water. Sister Wang thinks that woman is made of

hdu1818 It&#39;s not a Bug, It&#39;s a Feature!(隐式图最短路径Dijkstra)

题目链接:点击打开链接 题目描述:补丁在修bug时,有时也会引入新的bug,假设有n(n<=20)个潜在的bug和m(m<=100)个补丁,每个补丁用两个长度为n的字符串表示,其中字符串的每个位置表示一个bug.第一个串表示打补丁之前的状态('-'表示在该位置不存在bug,'+'表示该位置必须存在bug,0表示无所谓),第二个串表示打补丁之后的状态('-'表示不存在,'+'表示存在,0表示不变).每个补丁都有一个执行时间,你的任务是用最少的时间把一个所有bug都存在的软件通过打补丁的方式变得没

It&amp;#39;s not a Bug, It&amp;#39;s a Feature! (poj 1482 最短路SPFA+隐式图+位运算)

Language: Default It's not a Bug, It's a Feature! Time Limit: 5000MS   Memory Limit: 30000K Total Submissions: 1353   Accepted: 516 Description It is a curious fact that consumers buying a new software product generally do not expect the software to

【UVA】658 - It&#39;s not a Bug, it&#39;s a Feature!(隐式图 + 位运算)

这题直接隐式图 + 位运算暴力搜出来的,2.5s险过,不是正法,做完这题做的最大收获就是学会了一些位运算的处理方式. 1.将s中二进制第k位变成0的处理方式: s = s & (~(1 << pos)); 将s中二进制第k位变成1的处理方式: s = s | (1 << pos); 2.二进制运算: [1] & : 1 & 1 = 1 , 1 & 0 = 0 , 0 & 0 = 0; 快速判断奇偶性: if(a & 1);//为奇数

uva658(最短路径+隐式图+状态压缩)

题目连接(vj):https://vjudge.net/problem/UVA-658 题意:补丁在修正 bug 时,有时也会引入新的 bug.假定有 n(n≤20)个潜在 bug 和 m(m≤100) 个补丁,每个补丁用两个长度为 n 的字符串表示,其中字符串的每个位置表示一个 bug.第一 个串表示打补丁之前的状态("-" 表示该 bug 必须不存在,"+" 表示必须存在,0 表示无所 谓),第二个串表示打补丁之后的状态("-" 表示不存在,

poj1482(隐式图求最短路)

题目链接 题意:补丁在修正bug时,有时也会引入新的bug.假定有n个潜在的bug m个补丁,每个补丁用两个长度为n的字符串表示,其中字符串的每个位置表示一个bug,第一个串表示打补丁之前的状态('-'表示该bug必须不存在,'+'表示必须存在,0表示无所谓,第二个串表示打补丁之后的状态(-'表示不存在,'+'表示存在,0表示不变).每个补丁都有一个执行时间,你的任务使用最少的时间把一个bug都存在的软件通过打补丁的方式变得没有bug.一个补丁可以打多次. 解法:状压表示每个补丁的存在与否.隐式

hdoj 1226 超级密码 【隐式图BFS】

题目:hdoj 1226 超级密码 分析:这题属于隐式图搜索,状态不是很明显,需要自己建立. 其实搜索说白了就是暴力. 这个题目就是,首先对给出的可以组成的所有的数依次枚举,长度从小到大. 比如第一组样例,因为0不能出现在首位,那么我们枚举首位为1 和 7 看看漫步满足, 满足的话枚举第二位10 11 17 以及 70 71 77 顺便保存他们取余 n 之后的值,这样就可以剪枝,搜索过的就不用重复搜索了. 要求最早出现的BFS即可,第一个搜到的就是. 注意长度不大于500 AC代码: #incl