《挑战程序设计竞赛》2.5 最短路 AOJ0189 2249 2200 POJ3255 2139 3259 3268(5)
AOJ0189
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0189
题意
求某一办公室到其他办公室的最短距离。
多组输入,n表示n条关系,下面n次每次输入 x y d表示x到y的距离是d。需要注意的是n没有给定,需要根据输入来求。
输出办公室的编号和距离。
思路
任意两点之间的最短距离用floyd算法比较合适。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 10;
const int M = 10;
const int INF = 0x3f3f3f3f;
int d[N][N];
int n;
void input()
{
for (int i = 0; i < N; i ++)
fill(d[i], d[i]+N, INF);
int m;
cin >> m;
n = 0;
while ( m-- ) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
d[a][b] = d[b][a] = c;
n = max(max(n, a+1), b+1);
}
}
void solve()
{
for (int k = 0; k < n; k ++) {
for (int i = 0; i < n; i ++) {
for (int j = 0; j < n; j ++) {
d[i][j] = min(d[i][j], d[i][k]+d[k][j]);
}
}
}
int sum, msum = INF;
int id = 0;
for (int i = 0; i < n; i ++) {
sum = 0;
for (int j = 0; j < n; j ++) {
if (i == j) continue;
sum += d[i][j];
}
if (sum < msum) {
msum = sum;
id = i;
}
}
printf("%d %d\n", id, msum);
}
int main(void)
{
int m;
while ( cin >> m && m ) {
for (int i = 0; i < N; i ++)
fill(d[i], d[i]+N, INF);
n = 0;
while ( m-- ) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
d[a][b] = d[b][a] = c;
n = max(max(n, a+1), b+1);
}
solve();
}
return 0;
}
POJ2139
http://poj.org/problem?id=2139
题意
奶牛们最近要拍电影了……
1、若两个的奶牛一起工作则,他们相互的度(degrees)为;
2、若两只奶牛a、b不一起工作,但与另有一只奶牛都和他们工作,则a、b的相互的度为2。
求奶牛的与其他奶牛的度的平均值的100的整数。
思路
本题题意可以变换的理解为如果N个点在一个集合中,则这些点之间的距离为1。然后由此建立一个无向图。在这N个点中,每一个点与其他的所有点都有一个连接的路径长度,将这些长度都加起来,然后除以N-1,就求出了平均长度。题目所求为这些平均长度中的最小值,然后将最小值乘以100输出。
由于所有点到其他点的距离都要求,这个题用floyd算法最为合适,但也可用dijkstra算法计算N次求解,其中dij算法的实现又分使用邻接矩阵和邻接表两种实现方式。
因此解法有三种,我都实现了。
代码1(floyd)
Source Code
Problem: 2139 User: liangrx06
Memory: 368K Time: 32MS
Language: C++ Result: Accepted
Source Code
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 300;
const int INF = 0x3f3f3f3f;
int d[N+1][N+1];
int n;
void input()
{
int m;
cin >> n >> m;
for (int i = 1; i <= n; i ++)
fill(d[i]+1, d[i]+1+n, INF);
while ( m-- ) {
int k, movie[N];
cin >> k;
for (int i = 0; i < k; i++) {
scanf("%d", &movie[i]);
}
for (int i = 0; i < k; i++) {
for (int j = i+1; j < k; j++) {
d[movie[i]][movie[j]] = 1;
d[movie[j]][movie[i]] = 1;
}
}
}
}
void solve()
{
for (int k = 1; k <= n; k ++) {
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= n; j ++) {
d[i][j] = min(d[i][j], d[i][k]+d[k][j]);
}
}
}
int sum;
int msum = INF;
for (int i = 1; i <= n; i ++) {
sum = 0;
for (int j = 1; j <= n; j ++) {
if (i == j) continue;
sum += d[i][j];
}
msum = (sum < msum) ? sum : msum;
}
double res = (double)msum / (n-1) * 100;
printf("%d\n", (int)res);
}
int main(void)
{
input();
solve();
return 0;
}
代码2(dijkstra-邻接矩阵)
Source Code
Problem: 2139 User: liangrx06
Memory: 336K Time: 16MS
Language: C++ Result: Accepted
Source Code
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 300;
const int INF = 0x3f3f3f3f;
int cost[N+1][N+1];
int d[N+1];
bool v[N+1];
int n;
void input()
{
int m;
cin >> n >> m;
for (int i = 1; i <= n; i ++)
fill(cost[i]+1, cost[i]+1+n, INF);
while ( m-- ) {
int k, movie[N];
cin >> k;
for (int i = 0; i < k; i++) {
scanf("%d", &movie[i]);
}
for (int i = 0; i < k; i++) {
for (int j = i+1; j < k; j++) {
cost[movie[i]][movie[j]] = 1;
cost[movie[j]][movie[i]] = 1;
}
}
}
}
int dijkstra(int s)
{
fill(d+1, d+1+n, INF);
fill(v+1, v+1+n, false);
d[s] = 0;
while ( true ) {
int u = -1;
for (int i = 1; i <= n; i ++) {
if ( !v[i] && ( u == -1 || d[i] < d[u] ) )
u = i;
}
if ( u == -1 )
break;
v[u] = true;
for (int i = 1; i <= n; i ++) {
if ( !v[i] && d[u] + cost[u][i] < d[i] )
d[i] = d[u] + cost[u][i];
}
}
int sum = 0;
for (int i = 1; i <= n; i ++)
sum += d[i];
return sum;
}
void solve()
{
int sum;
int msum = INF;
for (int i = 1; i <= n; i ++) {
sum = dijkstra(i);
msum = (sum < msum) ? sum : msum;
}
double res = (double)msum / (n-1) * 100;
printf("%d\n", (int)res);
}
int main(void)
{
input();
solve();
return 0;
}
代码3(dijkstra-邻接表)
Source Code
Problem: 2139 User: liangrx06
Memory: 236K Time: 32MS
Language: C++ Result: Accepted
Source Code
#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;
const int N = 300;
const int INF = 0x3f3f3f3f;
struct Edge {
int to, cost;
Edge(int t, int c) {
to = t;
cost = c;
}
};
typedef pair<int, int> P;
int n;
int d[N+1];
vector<Edge> G[N+1];
void input()
{
int m;
cin >> n >> m;
while ( m-- ) {
int k, movie[N];
cin >> k;
for (int i = 0; i < k; i++) {
scanf("%d", &movie[i]);
}
for (int i = 0; i < k; i++) {
for (int j = i+1; j < k; j++) {
G[movie[i]].push_back(Edge(movie[j], 1));
G[movie[j]].push_back(Edge(movie[i], 1));
}
}
}
}
int dijkstra(int s) {
priority_queue<P, vector<P>, greater<P> > que;
fill(d+1, d+1+n, INF);
d[s] = 0;
que.push(P(0, s));
while ( !que.empty() ) {
P p = que.top(); que.pop();
int u = p.second;
if (d[u] < p.first) continue;
for (int i = 0; i < G[u].size(); i++) {
Edge e = G[u][i];
if ( d[e.to] > d[u] + e.cost) {
d[e.to] = d[u] + e.cost;
que.push(P(d[e.to], e.to));
}
}
}
int sum = 0;
for (int i = 1; i <= n; i ++)
sum += d[i];
return sum;
}
void solve()
{
int sum;
int msum = INF;
for (int i = 1; i <= n; i ++) {
sum = dijkstra(i);
msum = (sum < msum) ? sum : msum;
}
double res = (double)msum / (n-1) * 100;
printf("%d\n", (int)res);
}
int main(void)
{
input();
solve();
return 0;
}
《挑战程序设计竞赛》2.5 最短路 AOJ0189 2249 2200 POJ3255 2139 3259 3268(5)的更多相关文章
- Aizu 2249Road Construction 单源最短路变形《挑战程序设计竞赛》模板题
King Mercer is the king of ACM kingdom. There are one capital and some cities in his kingdom. Amazin ...
- 《挑战程序设计竞赛》2.3 动态规划-优化递推 POJ1742 3046 3181
POJ1742 http://poj.org/problem?id=1742 题意 有n种面额的硬币,面额个数分别为Ai.Ci,求最多能搭配出几种不超过m的金额? 思路 据说这是传说中的男人8题呢,对 ...
- 挑战程序设计竞赛》P345 观看计划
<挑战程序设计竞赛>P345 观看计划 题意:一周一共有M个单位的时间.一共有N部动画在每周si时 ...
- POJ 2386 Lake Counting 题解《挑战程序设计竞赛》
地址 http://poj.org/problem?id=2386 <挑战程序设计竞赛>习题 题目描述Description Due to recent rains, water has ...
- poj 3253 Fence Repair 贪心 最小堆 题解《挑战程序设计竞赛》
地址 http://poj.org/problem?id=3253 题解 本题是<挑战程序设计>一书的例题 根据树中描述 所有切割的代价 可以形成一颗二叉树 而最后的代价总和是与子节点和深 ...
- 迷宫问题_BFS_挑战程序设计竞赛p34
给定一个N*M的迷宫,求从起点到终点的最小步数. N,M<100: 输入: 10 10#S######.#......#..#.#.##.##.#.#........##.##.####.... ...
- 《挑战程序设计竞赛》 4.1.1 矩阵 P286
想写几篇挑战的感悟,也有助于自己理解这本书.但这上面大多贴的是书上的代码,主要是为了用的时候后直接复制就好了,这样就很方便了,就相当于黑盒模板了. 1.线性方程组 /** \brief 高斯消元法 * ...
- 【网络流#9】POJ 2135 Farm Tour 最小费用流 - 《挑战程序设计竞赛》例题
[题意]给出一张无向图,从1开始到n,求两条没有公共边的最短路,使得路程总和最小 每条边的权值设为费用,最大流量设为1,然后就是从源点到汇点流量为2的最小费用流. 因为是规定了流量,新建一个源点和一个 ...
- 《挑战程序设计竞赛》2.1 深度优先搜索 POJ2386 POJ1979 AOJ0118 AOJ0033 POJ3009
POJ2386 Lake Counting Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 25366 Accepted: ...
随机推荐
- 数据库出错提示Duplicate entry * for key *的解决方法
错误编号:1062 错误提示: 查询语句错误] ERR: Duplicate entry ' for key 'PRIMARY' SQL: ' PHP: misc.php: ; IP 问题分析: 向唯 ...
- 点滴积累【C#】---C#实现上传word将路径保存到数据库,文件保存到服务器。并且按照名称读取服务器的word
效果: 1. . . 数据库: 思路: 上传:先获取word物理地址,然后根据文件的类型判断,然后再保存到相应的文件夹下,再把路径插入到数据库中. 读取:首先根据输入的文件名字在数据库中查找出来文件的 ...
- Bash中的括号(三)
1.两个小括号用来对整数进行算术运算和逻辑运算,比如. 例如给变量赋值: $ a=+; echo $a + $ (( b = + )); echo $b 1+1 只是一个字符串,而 b 就是一个算术表 ...
- Atitit php序列化 php的serialize序列化和json序列化
Atitit php序列化 php的serialize序列化和json序列化 PHP 对不同类型的数据用不同的字母进行标示,Yahoo 开发网站提供的Using Serialized PHP with ...
- log4c面向对象设计 (转)
转自 http://blog.csdn.net/xkarl/article/details/6340180 Log4C,Log4CPlus/Log4cpp,Log4j,Log4Net,Log4Perl ...
- 安装好Oracle和PLSQLDeveloper后,PLSQLDeveloper登录时没有可选数据库和连接为问题
1.登录PL/SQL Developer 这里省略Oracle数据库和PL/SQL Developer的安装步骤,注意在安装PL/SQL Developer软件时,不要安装在Program Files ...
- #include""和#include<>的区别
一般来说,就是搜索路径不同 #include ""先去搜用户当前路径(也就是调用编译器的路径),然后再去搜用户用-I选项指定的路径,最后再去搜索编译器默认指定的路径(也就是所谓的系 ...
- Unity5.1 新的网络引擎UNET(四) UNET Remote Actions
孙广东 2015.7.12 网络系统 具有网络中执行操作actions 的方法.这些类型的actions 有时是调用远程过程调用(Remote Procedure Calls). 在网络系统中有两 ...
- 基于ffmpeg 直播推流和播放rtmp (IOS源码)
ios直播推流每秒能达到30帧,比安卓要强,视频采用软编码的话手机会发烫,得采用码编码,播放视频采用opengl渲染. ffmpeg初始化代码如下: int init_Code(int width, ...
- hdu5536 Chip Factory 字典树+暴力 处理异或最大 令X=(a[i]+a[j])^a[k], i,j,k都不同。求最大的X。
/** 题目:hdu5536 Chip Factory 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题意:给定n个数,令X=(a[i]+a[j] ...