原题下载: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. 【转】 java自定义注解

    java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明.配置的功能. 注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用.包含在 java.lang.annot ...

  2. DB天气app冲刺二阶段第四天

    今天就进度来说没有丝毫进度..考虑直接把数据库文件弄到代码里.因为每次挑选城市的时候都有时会出bug ,所以我想明天试一下看看是不是这个的问题,虽然工程量有点大,但是应该不困难,所以明天试一下需要. ...

  3. foxmail创建163公司企业邮箱的时候会出现ERR Unable to log on

    foxmail创建163公司企业邮箱的时候会出现ERR Unable to log on 解决办法:把pop.qiye.163.com更改为pop.ym.163.com,瞬间创建成功....也许是网易 ...

  4. SQL Server表分区【转】

    转自:http://www.cnblogs.com/knowledgesea/p/3696912.html SQL Server表分区   什么是表分区 一般情况下,我们建立数据库表时,表数据都存放在 ...

  5. 2208: [Jsoi2010]连通数 - BZOJ

    Description Input 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i行第j列的1表示顶点i到j有边,0则表示无边. Output 输出一行一个整数,表示该图 ...

  6. mysql federated engine

    mysql)) -> engine=federated -> connection='mysql://root@localhost:3306/t1/t';

  7. Codeforces Round #359 (Div. 2) D. Kay and Snowflake 树的重心

    题目链接: 题目 D. Kay and Snowflake time limit per test 3 seconds memory limit per test 256 megabytes inpu ...

  8. 【转载】Spring中的applicationContext.xml与SpringMVC的xxx-servlet.xml的区别

    一直搞不明白两者的区别. 如果使用了SpringMVC,事实上,bean的配置完全可以在xxx-servlet.xml中进行配置.为什么需要applicationContext.xml?一定必须? 一 ...

  9. HDU 2821 Pusher

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2821 首先,题目描述给的链接游戏很好玩,建议先玩几关,后面越玩越难,我索性把这道题A了,也就相当于通关 ...

  10. 20160730noip模拟赛zld

    codeforces394E 如果没有在凸多边形内一点的限制,答案肯定是 如果不在凸多边形内,那么目标点肯定在凸多边形边上,我们枚举每条边,在每条边上求出距离平方和最小的点,在这些点中求出最小的 我们 ...