原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf

题目翻译:

试题来源

  ACM/ICPC World Finals 2013 C

问题描述

  你现在要为智能汽车负责设计一种很高级的集中管理系统。目的是利用全球信息指导早上从郊区赶往市中心的乘客如何在避免交通堵塞的情况下更好地到达城市中心。
  不幸的是,乘客们对城市非常了解,而且都相当自私,你不能简单地甩给他们一条比平常走的还要长的路径(否则他们会直接无视你的指导),所以只能说服他们改走另外一条长度相同的路径。
  城市的道路网络由路口和连接它们的双向道路组成,通过不同的道路所需时间是不同的。所有乘客都会从各自的路口出发,当然不同的乘客出发的路口可能不同。但是所有乘客都会在同一个地点结束他们的旅程,那就是位于路口1的市中心。如果两个乘客试图在相同的时间,从同一方向,开始沿着相同的道路移动,就会出现堵塞——这是你必须避免种情况的。但是,两名乘客可以在同一时间通过同一个路口,或者在不同时间从同一条道路沿同一方向出发。
  请确定最多能有多少人能够在没有堵塞的前提下开车前往市中心。注意,所有乘客刚好在同一时间从他们所在路口出发,而且乘客只会走能够最快到达路口1的路径。

  在图C.1中,汽车图案标记了每名乘客最开始所在的路口,其中一辆车已经在市中心了。而路口4的车辆,可以走通过路口3的红色的点线,或者通过路口2的蓝色虚线。但是剩下的两辆车不可能在避免堵塞的前提下前往市中心。所以,在避免堵塞的情况下,最多只有3辆车能够抵达位于路口1的市中心。

输入格式

  输入只会包含一组数据。第一行是三个正整数n,m,c,其中n(1≤n≤25000)是路口的个数,m(0≤m≤50000)是连接路口的道路的个数,而c(1≤c≤1000)则是乘客的个数。接下来m行,每行有三个正整数xi,yi,ti来描述一条道路,xi,yi是该道路连接的两个不同的路口,而ti,是开车通过这个道路的时间(两个方向的时间一样)。所有的路口都能够抵达市中心。最后一行的c个数,分别代表了c个乘客出发的路口。

输出格式

  一个整数,表示在没有堵塞的情况下最多有多少乘客能够抵达市中心。

样例输入

3 3 2
1 2 42
2 3 1
2 3 1
2 3

样例输出

2

样例输入

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

样例输出

3

题目大意:

有n个城市和m条双向道路,每条道路的同一方向在同一时刻只能通过一辆车,现在有C辆车分布在这些城市中,他们想要到1号城市,并且一定要走最短路,问最多能有多少辆车可以按要求到达(不能被堵在半道上)

思路分析:

这道题十分类似于之前写过的SGU185,要求最短路的条数。所以一开始我们一1号城市为起点做一遍单源最短路,求出第 i 号城市到1 号城市的举例dist[i],并将所有不是在最短路上的边删去,然后准备求最大流。注意到拥堵只有可能发生在两辆车的起点具有相同的dist值的时候,所以我们可以按照dist值对车的起点排序,然后每次将相同dist值的车辆起点与源点相连,原来的删边之后的图照拷过去(注意到删边之后原来的无向图就变成了一棵有向树),然后求最大流即可

算法过程:

1、读入并建图,无向边按照两条有向边处理。

2、求所有点到1的最短路,使用SPFA或Dijkstra均可

3、将所有不可能在最短路上的边删掉(打上一个删除标记即可),剩下的图记为图M

4、读入c 辆车的起点,并按照这些店的dist值排序

5、将图M拷贝到当前的残量网络中(边的容量为1),新建源点并向dist值相同的起点连边,求一遍最大流,将最大流累加到答案中

6、重复第5步直至处理完所有的起点,输出答案

复杂度分析:

本题的理论渐进复杂度比较大,但事实上并没有被卡的那么死,建图的复杂度是O(m),最短路、删边复杂度O(m),第5步要做c次,它的复杂度是\(O(c*(m+n^{2}m))\),总渐进复杂度就是\(O(c*(m+n^{2}m))\)

参考代码:

 //date 20140122
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; const int maxn = ;
const int maxm = ;
const int maxc = ;
const int INF = 0x7FFFFFFF; inline int getint()
{
int ans (); char w = getchar();
while(w < '' || w > '')w = getchar();
while('' <= w && w <= '')
{
ans = ans * + w - '';
w = getchar();
}
return ans;
} inline int min(int a, int b){return a < b ? a : b;}
inline int max(int a, int b){return a > b ? a : b;} int n, m, c; struct edge
{
int u, v, w, c, next;
}Etmp[maxm], E[maxm];
int deled[maxm];
int atmp[maxn], a[maxn];
int nedgetmp, nedge; inline void addtmp(int u, int v, int w)
{
Etmp[++nedgetmp].v = v;
Etmp[nedgetmp].u = u;
Etmp[nedgetmp].w = w;
Etmp[nedgetmp].next = atmp[u];
atmp[u] = nedgetmp;
} inline void add(int u, int v, int c)
{
E[++nedge].v = v;
E[nedge].u = u;
E[nedge].c = c;
E[nedge].next = a[u];
a[u] = nedge;
} int dis[maxn]; inline void SPFA()
{
static int q[maxn];
static int inq[maxn];
int l = , r = ;
memset(dis, 0x7F, sizeof dis);
memset(inq, , sizeof inq);
dis[] = ; inq[] = ; q[] = ;
while(l < r)
{
int x = q[(++l) % maxn];
for(int i = atmp[x]; i; i = Etmp[i].next)
if(dis[Etmp[i].v] > dis[x] + Etmp[i].w)
{
dis[Etmp[i].v] = dis[x] + Etmp[i].w;
if(!inq[Etmp[i].v])
{
inq[Etmp[i].v] = ;
q[(++r) % maxn] = Etmp[i].v;
}
}
inq[x] = ;
}
for(int i = ; i <= n; ++i)printf("%d ", dis[i]);
printf("\n");
} inline void deledge()
{
memset(deled, , sizeof deled);
for(int i = ; i <= nedgetmp; ++i)
if(dis[Etmp[i].u] + Etmp[i].w > dis[Etmp[i].v])deled[i] = ;
} int s, t;
int lab[maxn], now[maxn]; inline int label()
{
static int q[maxn];
memset(lab, 0xFF, sizeof lab);
int l = , r = ;
q[] = s; lab[s] = ;
while(l < r)
{
int x = q[++l];
for(int i = a[x]; i; i = E[i].next)
if(E[i].c > && lab[E[i].v] == -)
{
lab[E[i].v] = lab[x] + ;
q[++r] = E[i].v;
}
}
// for(int i = 1; i <= s; ++i)
// fprintf(stderr, "%d ", lab[i]);
// fprintf(stderr, "\n");
return lab[t] != -;
} int Dinic(int v, int f)
{
if(v == t)return f;
int w, res = ;
for(int i = now[v]; i; i = now[v] = E[i].next)
if((E[i].c > ) && (f > ) && (lab[E[i].v] == lab[v] + ) && (w = Dinic(E[i].v, min(f, E[i].c))))
{
res += w;
E[i].c -= w;
E[i ^ ].c += w;
f -= w;
if(f == )break;
}
return res;
} inline int max_flow()
{
int ans = ;
while(label())
{
for(int i = ; i <= s; ++i)now[i] = a[i];
ans += Dinic(s, INF);
}
// printf("%d\n", ans);
return ans;
} int tar[maxc]; inline bool cmptar(int a, int b)
{
return dis[a] < dis[b];
} inline void rebuild(int l, int r)
{
nedge = ;
memset(a, , sizeof a);
for(int i = ; i <= nedgetmp; ++i)
if(!deled[i]){add(Etmp[i].v, Etmp[i].u, ); add(Etmp[i].u, Etmp[i]., );}
for(int i = l; i <= r; ++i) {add(s, tar[i], ); add(tar[i], s, );}
// for(int i = 2; i <= nedge; ++i)fprintf(stderr, "%d %d %d %d %d\n", i, E[i].u, E[i].v, E[i].c, E[i].next);
} inline int solve()
{
int ans = , now = dis[tar[]], l = , r = ;
for(int i = ; i <= c + ; ++i)
{
if(dis[tar[i]] == now)++r;
else
{
if(l == r)++ans;
else
{
rebuild(l, r);
ans += max_flow();
}
now = dis[tar[i]];
l = r = i;
}
}
return ans;
} int main()
{
freopen("congest.in", "r", stdin);
freopen("congest.out", "w", stdout); n = getint(); m = getint(); c = getint();
nedgetmp = ; nedge = ;
s = n + ; t = ;
for(int i = ; i <= m; ++i)
{
int x, y, t;
x = getint(); y = getint(); t = getint();
addtmp(x, y, t); addtmp(y, x, t);
}
SPFA();
deledge(); for(int i = ; i <= c; ++i)tar[i] = getint();
sort(tar + , tar + c + , cmptar); int ans = solve();
printf("%d\n", ans);
return ;
}

需要注意的问题:

1、之所以每次都需要重新建图,是因为跑完最大流之后我们剩下的图是上一次网络流的残量网络,图的结构已经发生了变化,所以必须重建

2、如果具有某一dist值的起点只有一个,那么它不会和其它车辆发生冲突,也自然无需重建图、求最大流了,直接将答案+1即可

3、从渐进复杂度角度来看这题肯定超时,所以无论用哪种网络流算法一定要将它优化到底(实践证明SAP的效果远不如Dinic)

ACM - ICPC World Finals 2013 C Surely You Congest的更多相关文章

  1. ACM - ICPC World Finals 2013 A Self-Assembly

    原题下载 : http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 这道题其实是2013年我AC的第一道题,非常的开心,这 ...

  2. ACM - ICPC World Finals 2013 F Low Power

    原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 问题描述 有n个机器,每个机器有2个芯片,每个 ...

  3. ACM - ICPC World Finals 2013 I Pirate Chest

    原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 问题描述 海盗Dick受够了在公海上厮杀.抢劫 ...

  4. ACM - ICPC World Finals 2013 H Матрёшка

    原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 问题描述 俄罗斯套娃是一些从外到里大小递减的传 ...

  5. ACM - ICPC World Finals 2013 D Factors

    原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 题目翻译: 问题描述 一个最基本的算数法则就是大于1的整数 ...

  6. ACM - ICPC World Finals 2013 B Hey, Better Bettor

    原题下载:http://icpc.baylor.edu/download/worldfinals/problems/icpc2013.pdf 这题真心的麻烦……程序不长但是推导过程比较复杂,不太好想 ...

  7. [算法竞赛入门经典]Message Decoding,ACM/ICPC World Finals 1991,UVa213

    Description Some message encoding schemes require that an encoded message be sent in two parts. The ...

  8. UVa210 Concurrency Simulator (ACM/ICPC World Finals 1991) 双端队列

    Programs executed concurrently on a uniprocessor system appear to be executed at the same time, but ...

  9. 谜题 (Puzzle,ACM/ICPC World Finals 1993,UVa227)

    题目描述:算法竞赛入门经典习题3-5 题目思路:模拟题 #include <stdio.h> #include <string.h> #define maxn 55 char ...

随机推荐

  1. jquery中的事件

    一.事件参数   function(event){} 1.停止冒泡事件  event.stopPropagation()  <=>  return false;2.阻止默认行为  even ...

  2. 【BZOJ】【3669】【NOI2014】魔法森林

    LCT动态维护MST LCT动态维护MST 我们可以枚举a,然后找从1到n的一条路径使得:这条路径上的b的最大值最小.这个路径肯定在MST上……所以枚举一遍所有的边,动态维护一个关于b值的MST即可. ...

  3. xargs 加 gm批量转换图片

    %x50% @ ../-\ 南澳西涌_50%/@ 看了很多说明上都在用-i,这是一个已经废弃了的参数

  4. Class Object

    java.lang Class Object java.lang.Object public class Object Class Object is the root of the class hi ...

  5. POJ2480 Longge's problem gcd&&phi

    题意简洁明了.做这题主要是温习一下phi的求法.令gcd(i,n)=k,实际上我们只需要求出有多少个i使得gcd(i,n)=k就可以了,然后就转化成了求phi(n/k)的和,但是n很大,我们不可能预处 ...

  6. POJ 1456 Supermarket(贪心+并查集优化)

    一开始思路弄错了,刚开始想的时候误把所有截止时间为2的不一定一定要在2的时候买,而是可以在1的时候买. 举个例子: 50 2  10 1   20 2   10 1    50+20 50 2  40 ...

  7. vector、string实现大数加法乘法

    理解 vector 是一个容器,是一个数据集,里边装了很多个元素.与数组最大的不同是 vector 可以动态增长. 用 vector 实现大数运算的关键是,以 string 的方式读入一个大数,然后将 ...

  8. 毕向东JAVA视频讲解笔记(前三课)

    1,定义一个类,因为java程序都定义类中,java程序都是以类的形式存在的,类的形式其实就是一个字节码文件最终体现. 2,定义一个主函数.为了让该类可以独立运行. 3,因为演示hello world ...

  9. 什么是hibernate?

    一.什么是hibernate框架?1.通过数据库保存java运行时产生的对象和恢复对象,其实就是实现java对象与关系数据库记录的映射关系称为ORM(Object Relation Mapping), ...

  10. python 编码问题(二)

    >>> a = '中文' >>> chardet.detect(a) {'confidence': 0.7525, 'encoding': 'utf-8'} > ...