hdu4725 拆点+最短路

题意:有 n 个点,每个点有它所在的层数,最多有 n 层,相邻两层之间的点可以互相到达,消耗 c (但同一层并不能直接到达),然后还有一些额外的路径,可以在两点间互相到达,并且消耗一定费用。问 1 点到 n 点的最小花费

将每一层拆成两个点,分别为进入层和出发层,然后相邻层的出发层可以指向进入层,花费 c,每个点可以到达其出发层,而进入层可以到达该点,花费 0 ,最后建立其余双向边,最短路

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<vector>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 typedef pair<int,int> pii;
 8
 9 struct cmp{
10     bool operator()(pii a,pii b){
11         return a.first>b.first;
12     }
13 };
14
15 int head[300005],point[1000005],val[1000005],nxt[1000005],size;
16 int n,dist[300005];
17
18 void add(int a,int b,int v){
19     point[size]=b;
20     val[size]=v;
21     nxt[size]=head[a];
22     head[a]=size++;
23 }
24
25 void dij(){
26     int i;
27     memset(dist,-1,sizeof(dist));
28     dist[1]=0;
29     priority_queue<pii,vector<pii>,cmp>q;
30     q.push(make_pair(dist[1],1));
31     while(!q.empty()){
32         pii u=q.top();
33         q.pop();
34         if(u.first>dist[u.second])continue;
35         for(i=head[u.second];~i;i=nxt[i]){
36             int j=point[i],v=u.first+val[i];
37             if(dist[j]==-1||dist[j]>v){
38                 dist[j]=v;
39                 q.push(make_pair(dist[j],j));
40             }
41         }
42     }
43     printf("%d\n",dist[n]);
44 }
45
46 int main(){
47     int t;
48     while(scanf("%d",&t)!=EOF){
49         for(int q=1;q<=t;q++){
50             printf("Case #%d: ",q);
51             memset(head,-1,sizeof(head));
52             size=0;
53             int m,c;
54             scanf("%d%d%d",&n,&m,&c);
55             int i,j;
56             for(i=1;i<=n;i++){
57                 int l;
58                 scanf("%d",&l);
59                 add(i,l+n,0);
60                 add(l+n+n,i,0);
61             }
62             for(i=1;i<n;i++){
63                 add(i+n,i+n+n+1,c);
64                 add(i+n+1,i+n+n,c);
65             }
66             for(i=1;i<=m;i++){
67                 int a,b,v;
68                 scanf("%d%d%d",&a,&b,&v);
69                 add(a,b,v);
70                 add(b,a,v);
71             }
72             dij();
73         }
74     }
75     return 0;
76 }

时间: 2024-10-26 17:19:28

hdu4725 拆点+最短路的相关文章

题单二:图论500

http://wenku.baidu.com/link?url=gETLFsWcgddEDRZ334EJOS7qCTab94qw5cor8Es0LINVaGMSgc9nIV-utRIDh--2UwRLvsvJ5tXFjbdpzbjygEdpGehim1i5BfzYgYWxJmu ==========  以下是最小生成树+并查集=========================[HDU]1213         How Many Tables        基础并查集★1272         小

NOIP练习赛题目5

小象涂色 难度级别:C: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 小象喜欢为箱子涂色.小象现在有c种颜色,编号为0~c-1:还有n个箱子,编号为1~n,最开始每个箱子的颜色为1.小象涂色时喜欢遵循灵感:它将箱子按编号排成一排,每次涂色时,它随机选择[L,R]这个区间里的一些箱子(不选看做选0个),为之涂上随机一种颜色.若一个颜色为a的箱子被涂上b色,那么这个箱子的颜色会变成(a*b)modc.请问在k次涂色后,所有箱子颜色的编号和

XJOI网上同步训练DAY6 T1

思路:考试的时候直接想出来了,又有点担心复杂度,不过还是打了,居然是直接A掉,开心啊. 我们发现,Ai<=7,这一定是很重要的条件,我们考虑状态压缩,去枚举路径中出现了哪些数字,然后我们把原来n个点拆成 我们枚举数字的最小公倍数 个,因为如果一个数模某个数等于0,那么模它的因数也一定是0,因此我们的思路就是拆点最短路. 1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<al

test20190526 Noip 模拟赛 4

调整(tweak) [问题描述] 已给定一个 N个点 M条边的有向图,点编号为1到N,第i条边为 (ui,vi), 权值为 wi. 你可以进行一次操作,使得任意条边的权值变成非负整数.要求进行尽量少的操作次数,使 得点 1到点 N的最短路径长度变成 c. 题目保证, c小于在未进行任何操作之前的原图中 1到 N的最短路长度. [输入文件]tweak.in 输入文件tweak.in 第一行三个整数,第一行三个整数,N,M和 c 接下来 M行,每一条边的信息 ui,vi和 wi,第 i行的表述第 i

游戏:最短路,拆点

把问题抽象成图论应该不难(也许都不用抽象?),但是怎么建边怎么跑就千差万别了. 首先应该注意到的一点是坐标的范围是0-500,也就是501*501个位置,所以数组/队列不要开小. 另外题目给出的莉露露没说位置不能重复,所以每个点可能不止入队一次,仍然要注意数组大小. 刚开始一直在想复杂度与n挂钩的算法,但是它挂了. 可以发现,n与x*y的差距并不打,所以如果正解复杂度可接受n的话那么拿xy作为复杂度应该没有问题. 先大概讲一下考场上的暴力(80分,因为上面说的锅,把数组开大是88分): 考虑每个

HDOJ-4725(Dijikstra算法+拆点求最短路)

The Shortest Path in Nya Graph HDOJ-4725 这题是关于最短路的问题,但是和常规的最短路有点不同的就是这里多了层次这一结构. 为了解决这一问题可以把每一层抽象或者划分为两个点:入点和出点. 对于每个点,将所在层的入点和该点相连,再将该点和所在层的出点相连,权值都为0. 对于每一层,将该层的出点和上面一层,以及下面一层的入点相连,取值就是题目给的c. 对于其余的路径,则按照题意进行连接就行了. #include<cstdio> #include<algo

Bzoj 2763: [JLOI2011]飞行路线 拆点,分层图,最短路,SPFA

2763: [JLOI2011]飞行路线 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1694  Solved: 635[Submit][Status][Discuss] Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格.Alice和Bob现在要从一个城市沿着航线到达另一个城市

UVA 1048 - Low Cost Air Travel(最短路)

UVA 1048 - Low Cost Air Travel 题目链接 题意:给定一些联票,在给定一些行程,要求这些行程的最小代价 思路:最短路,一张联票对应几个城市就拆成多少条边,结点表示的是当前完成形成i,在城市j的状态,这样去进行最短路,注意这题有坑点,就是城市编号可能很大,所以进行各种hash 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> #in

POJ 2135 Farm Tour &amp;&amp; HDU 2686 Matrix &amp;&amp; HDU 3376 Matrix Again 费用流求来回最短路

累了就要写题解,最近总是被虐到没脾气. 来回最短路问题貌似也可以用DP来搞,不过拿费用流还是很方便的. 可以转化成求满流为2 的最小花费.一般做法为拆点,对于 i 拆为2*i 和 2*i+1,然后连一条流量为1(花费根据题意来定) 的边来控制每个点只能通过一次. 额外添加source和sink来控制满流为2. 代码都雷同,以HDU3376为例. #include <algorithm> #include <iostream> #include <cstring> #in