Problem Statement

We have a directed graph with \(N\) vertices and \(M\) edges. Edge \(i\) is directed from Vertex \(A_i\) to \(B_i\).and has a weight of \(C_i\).

Initially, there is a piece on Vertex \(v\). Takahashi and Aoki will play a game where they alternate turns moving the piece as follows:

  • If there is no edge that goes from the vertex on which the piece is placed, end the game.
  • If there are edges that go from the vertex on which the piece is placed, choose one of those edges and move the piece along that edge.

Takahashi goes first. Takahashi tries to minimize the total weight of the edges traversed by the piece, and Aoki tries to maximize it.

More formally, their objectives are as follows.

Takahashi gives the first priority to ending the game in a finite number of moves. If this is possible, he tries to minimize the total weight of the edges traversed by the piece.

Aoki gives the first priority to preventing the game from ending in a finite number of moves. If this is impossible, he tries to maximize the total weight of the edges traversed by the piece.

(If the piece traverses the same edge multiple times, the weight is added that number of times.)

Determine whether the game ends in a finite number of moves when both players play optimally. If it ends, find the total weight of the edges traversed by the piece.

Constraints

  • \(1≤N≤2×10^5\)
  • \(0≤M≤2×10^5\)
  • \(1\le v≤N\)
  • \(1≤A_i,B_i≤N\)
  • There is no multi-edges. That is, \((A_i,B_i)\ne (A_j,B_j)\) for \(i\ne j\)
  • There is no self-loops. That is, \(A_i\ne B_i\).
  • \(0≤C≤10 ^9\)
  • All values in input are integers.

Input

Input is given from Standard Input in the following format:

\(N\) \(M\) \(v\)

\(A_1\) \(B_1\) \(C_1\)

\(A_2\) \(B_2\) \(C_2\)



\(A_M\) \(B_M\) \(C_M\)

Output

If the game does not end in a finite number of moves when both players play optimally, print INFINITY.

If the game ends in a finite number of moves, print the total weight of the edges traversed by the piece.

Sample Input 1

7 6 1
1 2 1
1 3 10
2 4 100
2 5 102
3 6 20
3 7 30

Sample Output 1

40

First, Takahashi will move the piece to Vertex \(3\). Next, Aoki will move the piece to Vertex \(7\), and the game will end.

The total weight of the edges traversed by the piece will be \(10+30=40\).

Sample Input 2

3 6 3
1 2 1
2 1 2
2 3 3
3 2 4
3 1 5
1 3 6

Sample Output 2

INFINITY

The game will not end in a finite number of moves.

Sample Input 3

4 4 1
1 2 1
2 3 1
3 1 1
2 4 1

Sample Output 3

5

The piece will go \(1→2→3→1→2→4\).

假设图是一个有向无环图,那么直接使用 DAG 上 dp 即可。轮到 Alice 时在所有后继节点中取最小值。轮到 Bob 时在所有后继节点中取最大值。

那么如果是有环呢?有环的 min/max dp 的经典解法是跑最短路。把无后继的节点入堆,图建成反图,跑 dij 就行了。

但是这个 dp 有时候取最大值,有时候取最小值,好像很难处理。

首先如果轮到 Alice 的话,直接取最小值。因为 dij 的堆用小根堆,所以Alice的dp值直接跑dij是正确的。

但是如果轮到 Bob,他的值不像 Alice,需要所有的后继节点更新后,才能更新 Bob 的dp值。而且他是希望可以在博弈中跑出死循环的,所以如果不是所有的后继节点都更新得到,他就不更新。我们可以使用类似拓扑的方式处理。记录入度,然后松弛时入度减一。

那么想清楚代码就很好写了。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e5+5;
struct node{
int v,k;
LL w;
bool operator<(const node&n)const{
return w>n.w;
}
};
struct edge{
int v,nxt,w;
}e[N<<1];
int hd[N],n,m,s,u,v,w,e_num,in[N],vis[N][2];
LL dis[N][2];
priority_queue<node>q;
void add_edge(int u,int v,int w)
{
e[++e_num]=(edge){v,hd[u],w};
hd[u]=e_num;
}
void dijkstra()
{
for(int i=1;i<=n;i++)
{
if(!in[i])
{
q.push((node){i,0,0});
q.push((node){i,1,0});
}
else
dis[i][0]=0x7f7f7f7f7f7f7f7f;
}
// printf("%d\n",dis[1][0]);
while(!q.empty())
{
int v=q.top().v,k=q.top().k;
// printf("%d %d %d\n",v,k,dis[v][k]);
q.pop();
if(vis[v][k])
continue;
if(k)
{
for(int i=hd[v];i;i=e[i].nxt)
{
// if(v==2)
// printf("%d %d %d\n",e[i].v,dis[v][1]+e[i].w,dis[e[i].v][0]);
if(dis[v][1]+e[i].w<dis[e[i].v][0])
{
dis[e[i].v][0]=dis[v][1]+e[i].w;
q.push((node){e[i].v,0,dis[e[i].v][0]});
}
}
}
else
{
for(int i=hd[v];i;i=e[i].nxt)
{
in[e[i].v]--;
if(dis[v][0]+e[i].w>dis[e[i].v][1])
{
dis[e[i].v][1]=dis[v][0]+e[i].w;
// q.push((node){e[i].v,1,-dis[e[i].v][1]});
}
if(!in[e[i].v])
q.push((node){e[i].v,1,dis[e[i].v][1]});
}
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w),in[u]++;
add_edge(v,u,w);
}
dijkstra();
if(dis[s][0]>1e18)
printf("INFINITY");
else
printf("%lld",dis[s][0]);
}

[ABC261Ex] Game on Graph的更多相关文章

  1. [开发笔记] Graph Databases on developing

    TimeWall is a graph databases github It be used to apply mathematic model and social network with gr ...

  2. Introduction to graph theory 图论/脑网络基础

    Source: Connected Brain Figure above: Bullmore E, Sporns O. Complex brain networks: graph theoretica ...

  3. POJ 2125 Destroying the Graph 二分图最小点权覆盖

    Destroying The Graph Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8198   Accepted: 2 ...

  4. [LeetCode] Number of Connected Components in an Undirected Graph 无向图中的连通区域的个数

    Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...

  5. [LeetCode] Graph Valid Tree 图验证树

    Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...

  6. [LeetCode] Clone Graph 无向图的复制

    Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's ...

  7. 讲座:Influence maximization on big social graph

    Influence maximization on big social graph Fanju PPT链接: social influence booming of online social ne ...

  8. zabbix利用api批量添加item,并且批量配置添加graph

    关于zabbix的API见,zabbixAPI 1item批量添加 我是根据我这边的具体情况来做的,本来想在模板里面添加item,但是看了看API不支持,只是支持在host里面添加,所以我先在一个ho ...

  9. Theano Graph Structure

    Graph Structure Graph Definition theano's symbolic mathematical computation, which is composed of: A ...

  10. 纸上谈兵: 图 (graph)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 图(graph)是一种比较松散的数据结构.它有一些节点(vertice),在某些节 ...

随机推荐

  1. Linux 内核音频数据传递主要流程 (下)

    来而不往非礼也.前面看到了用户空间应用程序和 DMA buffer 之间交换数据,并更新 runtime->control->appl_ptr 指针的过程,这里看一下硬件设备驱动程序在完成 ...

  2. 每日一库:pprof简介

    pprof简介 pprof是Go语言的一个性能分析库,它可以帮助开发者找出程序中的性能瓶颈.pprof提供了CPU分析.内存分析.阻塞分析等多种性能分析功能. 以下是pprof的主要特性: CPU分析 ...

  3. 推荐一个react脚手架工具

    今天介绍一个react脚手架,react-cli, 可以说是 vue-cli 的外表,react的心! 安装步骤: npm install -g sao sao yang302/react-cli n ...

  4. numpy中矩阵的逆,求解,特征值,特征向量

    逆:numpy.linalg.inv() # 求矩阵的逆import numpy as npa=np.mat('1 0;0 1')#生成一个矩阵print(type(a))b=np.linalg.in ...

  5. 开发微信小程序技术栈

    开发微信小程序主要需要以下技术栈: 小程序框架参考文档 小程序组件参考文档 小程序 API 参考文档 小程序服务端 API 参考文档 微信开发者工具参考文档 微信云托管参考文档 微信云开发参考文档 1 ...

  6. CF276C

    题目简化和分析: 属于一种贪心思维,我们想如果要使得和最大,那么就必须保证最大的数乘的次数越多越好,并且排序没有限制,快速累加每个位置出现的次数,所以应该使用线段树差分. 然后排序最大乘最大累加. S ...

  7. MongoDB 中的锁分析

    MongoDB 中的锁 前言 MongoDB 中锁的类型 锁的让渡释放 常见操作使用的锁类型 如果定位 MongoDB 中锁操作 1.查询运行超过20S 的请求 2.批量删除请求大于 20s 的请求 ...

  8. Flyweight 享元模式简介与 C# 示例【结构型6】【设计模式来了_11】

    〇.简介 1.什么是享元模式? 一句话解释:   将相似或同类的对象共享同一个对象,将这些对象暂存在列表中,使用时直接取出,避免每次使用时都要新建浪费资源. 享元模式的目的是减少对象的创建,通过共享对 ...

  9. [Python急救站课程]太阳花的绘制

    太阳花的绘制 from turtle import * color('red', 'yellow') # 分别定义填充颜色 begin_fill() while True: forward(200) ...

  10. Redis Functions 介绍之一

    Redis提供了编程接口(programming interface)可以让你在Redis服务器端执行客户的脚本. 一个重大的变化就是从Redis 7开始,你可以选择使用Redis Functions ...