公路通行税Ceoi99(BFS+图的直径)
公路通行税(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+图的直径)的更多相关文章
- [Python] 弗洛伊德(Floyd)算法求图的直径并记录路径
相关概念 对于一个图G=(V, E),求图中两点u, v间最短路径长度,称为图的最短路径问题.最短路径中最长的称为图的直径. 其中,求图中确定的某两点的最短路径算法,称为单源最短路径算法.求图中任意两 ...
- [CSP-S模拟测试]:简单的操作(二分图+图的直径)
题目描述 从前有个包含$n$个点,$m$条边,无自环和重边的无向图. 对于两个没有直接连边的点$u,v$,你可以将它们合并.具体来说,你可以删除$u,v$及所有以它们作为端点的边,然后加入一个新点$x ...
- poj 1383 Labyrinth【迷宫bfs+树的直径】
Labyrinth Time Limit: 2000MS Memory Limit: 32768K Total Submissions: 4004 Accepted: 1504 Descrip ...
- codeforce 337D Book of Evil ----树形DP&bfs&树的直径
比较经典的老题 题目意思:给你一颗节点数为n的树,然后其中m个特殊点,再给你一个值d,问你在树中有多少个点到这m个点的距离都不大于d. 这题的写法有点像树的直径求法,先随便选择一个点(姑且设为点1)来 ...
- codeforces 690C2 C2. Brain Network (medium)(bfs+树的直径)
题目链接: C2. Brain Network (medium) time limit per test 2 seconds memory limit per test 256 megabytes i ...
- POJ 1383 Labyrinth (bfs 树的直径)
Labyrinth 题目链接: http://acm.hust.edu.cn/vjudge/contest/130510#problem/E Description The northern part ...
- 第46套题【STL】【贪心】【递推】【BFS 图】
已经有四套题没有写博客了.今天改的比较快,就有时间写.今天这套题是用的图片的形式,传上来不好看,就自己描述吧. 第一题:单词分类 题目大意:有n个单词(n<=10000),如果两个单词中每个字母 ...
- LOJ 3057 「HNOI2019」校园旅行——BFS+图等价转化
题目:https://loj.ac/problem/3057 想令 b[ i ][ j ] 表示两点是否可行,从可行的点对扩展.但不知道顺序,所以写了卡时间做数次 m2 迭代的算法,就是每次遍历所有不 ...
- We Need More Bosses CodeForces - 1000E(缩点 建图 求桥 求直径)
题意: 就是求桥最多的一条路 解析: 先求连通分量的个数 然后缩点建图 求直径即可 #include <bits/stdc++.h> #define mem(a, b) memset(a ...
随机推荐
- 【记录】Linux安装JDK详细步骤
Linux安装JDK步骤1. 先从网上下载jdk(jdk-1_5_0_02-linux-i586.rpm) ,推荐SUN的官方网站www.sun.com,下载后放在/home目录中,当然其它地方也行. ...
- ActiveMQ学习笔记(22)----ActiveMQ的优化和使用建议
1. 什么时候使用ActiveMQ 1. 异步通信 2. 一对多通信 3. 做个系统的集成,同构,异构 4. 作为RPC的替代 5. 多个应用相互解耦 6. 作为事件驱动架构的幕后支撑 7. 为了提高 ...
- SpringBoot学习笔记(15)----SpringBoot使用Druid
直接访问Druid官网wiki,有详细教程,地址如下: SpringBoot支持Druid地址:https://github.com/alibaba/druid/tree/master/druid-s ...
- 注解@SuppressWarnings
在JAVA中注解@SuppressWarnings("deprecation")的Deprecation是什么意思 过期的 @SuppressWarnings("depr ...
- 搭建appium环境
1.下载jdk1.8 配置环境变量 JAVA_HOME---------->你的jdk路径 path---------------------->%JAVA_HOME%\bin;%JAV ...
- [UVa10188]Automated Judge Script
题目大意:叫你写一个判断答案的系统. 解题思路:模拟即可.AC条件为,答案条数相等,所有字符相等.PE条件为,答案条数可能不等,所有数字字符相等.其他为WA. UVa现在的C++已经不支持gets了, ...
- state.sls web.apache
[root@master01 web]# salt 'node02' state.sls web.apache node02: ---------- ID: apache-inst ...
- 紫书 习题 11-12 UVa 1665 (并查集维护联通分量)
这道题要逆向思维 反过来从大到小枚举, 就是在矩阵中一点一点加进去数字,这样比较 好操作, 如果正着做就要一点一点删除数字, 不好做. 我们需要在这个过程中维护联通块的个数, 这里用到了并查集. 首先 ...
- 题解 洛谷 P4047 【[JSOI2010]部落划分】
我觉得几乎就是一道最小生成树模板啊... 题解里许多大佬都说选第n-k+1条边,可我觉得要这么讲比较容易理解 (虚边为能选的边,实边为最小生成树) 令n=5,k=2,(1,3)<(1,2)< ...
- HTTP——学习笔记(7)
HTTP中的认证机制 什么是认证机制?: 服务器需要知道客户端是谁. 怎样知道客户端身份?: 核对“登录者本人才知道的信息” 密码:只有本人才会知道的字符串信息 动态令牌:仅限本人持有的设备内显示的一 ...