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

题目链接: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 Pirated
2 3 3 Cracked
3 4 6 Licensed

答案应为 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;
}
原文地址:https://www.cnblogs.com/Blackops/p/5859302.html