公路通行税(Ceoi99)

版权声明:本篇随笔版权归作者YJSheep(www.cnblogs.com/yangyaojia)所有,转载请保留原地址!

在PALMIA国家内,有N个城市由公路相连(每条公路恰好双向连接两个城市)。经由一条公路或多条公路,从任一城市出发可以到达其余各个城市。直到今年,公路上才要征收公路通行税。在每条公路的中间,有一征税员,从每一辆经由此路的车收取 1 PALMIA COIN(1PC)。

政府官员决定减少收税员而推行公路印花。如果一辆车欲进入一条公路,就必须将这张印花贴在窗上。

政府官员决定:一年的公路印花的价值相当于在两个最远城市之间进行100次旅行所需的费用。两个城市之间的距离是从一个城市到达第二个城市所需经过的最少数目的公路数。

你的任务是编写一个程序计算出公路印花的价值。

输入数据:

输入文件中包含几组数据。每组的第一行包括整数N和M(中间被一个空格隔开),N是该国家中城市的数目,M是公路的数目(1≦N≦1000,1≦M≦2000)。城市由整数进行编号,从1到N。接下来的M行,每行均包含一对整数A,B(1≦A,B≦N),中间由一空格隔开,代表在城市A与B之间有一条公路。在最后一组数后仅有一行,是两个0,中间被一空格隔开。

输出数据:

对输入文件中的各组数据,输出文件中包含一行,表示公路印花的价值。

输入输出示例:

TOLLS.IN:

4 4

1 2

2 3

4 2

3 4

0 0

TOLLS.OUT:

200

解题报告

简单来说就是寻找图的直径,因为数据n<=1000,对于每个点用最短路为O(n*nlogn)是过不了的,但注意到路径长度只有1,所以我们可以用BFS,时间勉勉强前过去。不过,我们可以先对某个点用单源最短路。然后记录距离其最远的点,再依次对他们用BFS,这样效率会快很多而且答案也是正确的。

#include<bits/stdc++.h>
#define MAXN 1000+1
#define MAXM 500000+1
#define Pair pair<int,int>
using namespace std;
int n,m,t,v[MAXN],num;
int head[MAXN],g[MAXN][MAXN];
queue<Pair> emp;
struct Edge{
int dis;
int to,next;
}edge[MAXM];
int read()
{
int in=;
char ch=getchar();
for(;ch>''||ch<'';ch=getchar());
for(;ch>=''&&ch<='';ch=getchar()) in=in*+ch-'';
return in;
}
void add(int from,int to,int dis)
{
edge[++num].next=head[from];
edge[num].to=to;
edge[num].dis=dis;
head[from]=num;
}
void bfs(int s,int &maxl)
{
memset(v,,sizeof(v));
queue<Pair> h=emp;
h.push(Pair(,s));
while(h.size()>)
{
int k=h.front().second,diss=h.front().first;h.pop();v[k]=;
for(int i=head[k];i;i=edge[i].next)
if (v[edge[i].to]==)
{
v[edge[i].to]=;
g[edge[i].to][k]=g[k][edge[i].to]=diss+;
h.push(Pair(diss+,edge[i].to));
maxl=max(maxl,diss+);
}
}
}
void dij(int s)
{
memset(v,,sizeof(v));
priority_queue<Pair,vector<Pair>,greater<Pair> > h;
int dis[MAXN],maxx=;for(int i=;i<=n;i++) dis[i]=;
dis[s]=;
h.push(Pair(dis[s],s));
while(h.size()>)
{
int k=h.top().second;h.pop();
if(v[k]) continue;
v[k]=;
for(int i=head[k];i;i=edge[i].next)
{
if(dis[k]+edge[i].dis<dis[edge[i].to])
{
dis[edge[i].to]=dis[k]+edge[i].dis;
h.push(Pair(dis[edge[i].to],edge[i].to));
}
}
}
queue<int> q;
for(int i=;i<=n;i++)
if(dis[i]!=) maxx=max(maxx,dis[i]);
for(int i=;i<=n;i++) if(dis[i]==maxx) q.push(i);
if(maxx!=)
while(q.size()>)
{
bfs(q.front(),maxx);q.pop();
}
else
{
for(int i=;i<=n;i++)
{
bfs(i,maxx);
}
}
printf("%d\n",maxx*);
}
int main()
{ while(scanf("%d%d",&n,&m)==)
{
int maxl=;
if(m==&&n==) return ;
memset(edge,,sizeof(edge));
memset(g,,sizeof(g));
num=;//memset(dis,0,sizeof(dis));
memset(head,,sizeof(head));
for(int i=;i<=m;i++)
{
int a,b;a=read();b=read();
add(a,b,);
add(b,a,);
}
dij(); }
return ;
}

公路通行税Ceoi99(BFS+图的直径)的更多相关文章

  1. [Python] 弗洛伊德(Floyd)算法求图的直径并记录路径

    相关概念 对于一个图G=(V, E),求图中两点u, v间最短路径长度,称为图的最短路径问题.最短路径中最长的称为图的直径. 其中,求图中确定的某两点的最短路径算法,称为单源最短路径算法.求图中任意两 ...

  2. [CSP-S模拟测试]:简单的操作(二分图+图的直径)

    题目描述 从前有个包含$n$个点,$m$条边,无自环和重边的无向图. 对于两个没有直接连边的点$u,v$,你可以将它们合并.具体来说,你可以删除$u,v$及所有以它们作为端点的边,然后加入一个新点$x ...

  3. poj 1383 Labyrinth【迷宫bfs+树的直径】

    Labyrinth Time Limit: 2000MS   Memory Limit: 32768K Total Submissions: 4004   Accepted: 1504 Descrip ...

  4. codeforce 337D Book of Evil ----树形DP&bfs&树的直径

    比较经典的老题 题目意思:给你一颗节点数为n的树,然后其中m个特殊点,再给你一个值d,问你在树中有多少个点到这m个点的距离都不大于d. 这题的写法有点像树的直径求法,先随便选择一个点(姑且设为点1)来 ...

  5. codeforces 690C2 C2. Brain Network (medium)(bfs+树的直径)

    题目链接: C2. Brain Network (medium) time limit per test 2 seconds memory limit per test 256 megabytes i ...

  6. POJ 1383 Labyrinth (bfs 树的直径)

    Labyrinth 题目链接: http://acm.hust.edu.cn/vjudge/contest/130510#problem/E Description The northern part ...

  7. 第46套题【STL】【贪心】【递推】【BFS 图】

    已经有四套题没有写博客了.今天改的比较快,就有时间写.今天这套题是用的图片的形式,传上来不好看,就自己描述吧. 第一题:单词分类 题目大意:有n个单词(n<=10000),如果两个单词中每个字母 ...

  8. LOJ 3057 「HNOI2019」校园旅行——BFS+图等价转化

    题目:https://loj.ac/problem/3057 想令 b[ i ][ j ] 表示两点是否可行,从可行的点对扩展.但不知道顺序,所以写了卡时间做数次 m2 迭代的算法,就是每次遍历所有不 ...

  9. We Need More Bosses CodeForces - 1000E(缩点 建图 求桥 求直径)

    题意: 就是求桥最多的一条路 解析: 先求连通分量的个数 然后缩点建图  求直径即可 #include <bits/stdc++.h> #define mem(a, b) memset(a ...

随机推荐

  1. Ubuntu系统下Import cv2提示no modules ...错误

    最近利用pycharm在Ubuntu系统下调试一个Python项目,将pycharm的解释器从python2.7更换到python3.4后,程序中的Import cv2提示no modules nam ...

  2. Caffe学习--Net分析

    Caffe_Net 1.基本数据 vector<shared_ptr<Layer<Dtype> > > layers_; // 记录每一层的layer参数 vect ...

  3. 路飞学城Python-Day2

    13.变量的定义规范 变量的含义:变量就是定义之后还能发生改变,可以重新赋值的量;变量的定义规范:名字不能随便起,声明一个变量,name = "123"[变量 = 值]变量定义规则 ...

  4. css兼容性问题总结

    DIV+CSS设计IE6.IE7.FF 兼容性 DIV+CSS网页布局这是一种趋势,我也开始顺应这股趋势了,不过在使用DIV+CSS网站设计的时候,应该注意css样式兼容不同浏览器问题,特别是对完全使 ...

  5. BZOJ 3530 [SDOI2014]数数 (Trie图/AC自动机+数位DP)

    题目大意:略 裸的AC自动机+数位DP吧... 定义f[i][x][0/1]表示已经匹配到了第i位,当前位置是x,0表示没到上限,1到上限,此时数是数量 然而会出现虚拟前导零,即前几位没有数字的情况, ...

  6. 洛谷 P1373 小a和uim之大逃离 (差值型dp总结)

    这道题和多米诺骨牌那道题很像 ,都是涉及到差值的问题. 这道题是二维的,同时要取模. 这种题,因为当前的决策有后效性,会影响到差值,所以直接把 差值作为维度,然后计算答案的时候把差值为0的加起来就行了 ...

  7. Python seed() 函数--每次产生一样的随机数系列

    import random random.seed( 10 ) print("Random number with seed 10 : ", random.random()) #0 ...

  8. ping,telnet,ssh命令的理解

    ping主要用于测试到达目的主机的网络是否连接,但是它不能检测某个端口是否开放. ping 域名可以直接看出这个域名对应的ip ssh与telnet都是远程登录工具. ssh对传输加密,安全性高,te ...

  9. POJ3370&amp;HDU1808 Halloween treats【鸽巢原理】

    题目链接: id=3370">http://poj.org/problem?id=3370 http://acm.hdu.edu.cn/showproblem.php?pid=1808 ...

  10. 7、java封装、继承、聚合组合

    1封装:封装的是属性,封:private 装:set.get‘ 可以看做将属性和get/set方法捆绑的过程. 优点:1.防止对封装数据的未经授权的访问,提高安全性.使用者只能通过事先预定好的方法来访 ...