最短路径
2016-02-06 17:32
357 查看
/*
题目1100:最短路径
题目描述:
N个城市,标号从0到N-1,M条道路,第K条道路(K从0开始)的长度为2^K,求编号为0的城市到其他城市的最短距离
输入:
第一行两个正整数N(2<=N<=100)M(M<=500),表示有N个城市,M条道路
接下来M行两个整数,表示相连的两个城市的编号
输出:
N-1行,表示0号城市到其他城市的最短路,如果无法到达,输出-1,数值太大的以MOD 100000 的结果输出。
样例输入:
4 4
1 2
2 3
1 3
0 1
样例输出:
8
9
11
*/
#include<stdio.h>
#define maxsize 110
#define M 100000
int T[maxsize];
int E[maxsize][maxsize];
int visited[maxsize];
int findroot(int x)
{
int temp;
if(T[x]==-1)
return x;
else
{
temp=findroot(T[x]);
T[x]=temp;
return temp;
}
}
void dfs(int x,int n,int sum)
{
int i;
for(i=0;i<n;i++)
if(visited[i]==0&&E[x][i]!=0)
{
visited[i]=1;
T[i]=sum+E[x][i];
dfs(i,n,T[i]);
}
}
int main()
{
int m,n,a,k,b,i,j,num,sum,roota,rootb;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(i=0;i<n;i++)
{
T[i]=-1;
visited[i]=0;
}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
E[i][j]=0;
k=1;
for(i=0;i<m;i++)
{
scanf("%d %d",&a,&b);
roota=findroot(a);
rootb=findroot(b);
if(roota!=rootb)
{
T[rootb]=roota;
E[a][b]=k%M;
E[b][a]=k%M;
}
k=(k*2)%M;
}
i=0;
sum=0;
visited[0]=1;
for(i=1;i<n;i++)
T[i]=-1;
dfs(0,n,sum);
for(i=1;i<n;i++)
printf("%d\n",T[i]%M);
}
return 0;
}
由于第i条边的权值w[i] = 2^i,那么前i-1条边的权值之和为w[0]+w[1]+·+w[i-1] =(2^i)-1
也就是说前i-1条边的权值之和小于第i条边。
根据这一性质,当添加第i条边(a,b)时:
若a,b未连通,则a,b间的最短路径为w[i];
若a,b已经连通,则a,b之间的最短路径保持不变。
#include<cstdio>
#include<fstream>
using namespace std;
#define MAX 550
#define INF 9999999
#define M 100000
int father[MAX], rank[MAX];
int d[MAX][MAX];
void init ( int n )
{
for ( int i = 0; i < n; i++ )
{
father[i] = i;
rank[i] = 1;
d[i][i] = 0;
}
}
int Find ( int i )
{
if ( i != father[i] )
father[i] = Find(father[i]);
return father[i];
}
void Union ( int a, int b )
{
int ta = Find(a);
int tb = Find(b);
if ( ta == tb ) return;
if ( rank[a] >= rank[b] )
{
father[tb] = ta;
rank[ta] += rank[tb];
}
else
{
father[ta] = tb;
rank[tb] += rank[ta];
}
}
int mod_exp ( long long a, long long b )
{
long long ret = 1;
while ( b > 0 )
{
if ( b & 1 )
ret = ( ret * a ) % M;
b >>= 1;
a = ( a * a ) % M;
}
return ret;
}
int main()
{
int n, m, i, j, k;
int a, b, ta, tb, dist;
while ( scanf("%d%d",&n,&m) != EOF )
{
init(n);
for ( k = 0; k < m; k++ )
{
scanf("%d%d",&a,&b);
ta = Find(a);
tb = Find(b);
if ( ta == tb ) continue;
dist = mod_exp(2,k);
for ( i = 0; i < n; i++ )
{
if ( Find(i) != ta ) continue;
for ( j = 0; j < n; j++ )
{
if ( Find(j) != tb ) continue;
d[i][j] = (d[i][a] + dist + d[b][j]) % M;
d[j][i] = d[i][j];
}
}
Union(a,b);
}
ta = Find(0);
for ( i = 1; i < n; i++ )
{
if ( Find(i) == ta )
printf("%d\n",d[0][i]);
else printf("-1\n");
}
}
return 0;
}
题目1100:最短路径
题目描述:
N个城市,标号从0到N-1,M条道路,第K条道路(K从0开始)的长度为2^K,求编号为0的城市到其他城市的最短距离
输入:
第一行两个正整数N(2<=N<=100)M(M<=500),表示有N个城市,M条道路
接下来M行两个整数,表示相连的两个城市的编号
输出:
N-1行,表示0号城市到其他城市的最短路,如果无法到达,输出-1,数值太大的以MOD 100000 的结果输出。
样例输入:
4 4
1 2
2 3
1 3
0 1
样例输出:
8
9
11
*/
#include<stdio.h>
#define maxsize 110
#define M 100000
int T[maxsize];
int E[maxsize][maxsize];
int visited[maxsize];
int findroot(int x)
{
int temp;
if(T[x]==-1)
return x;
else
{
temp=findroot(T[x]);
T[x]=temp;
return temp;
}
}
void dfs(int x,int n,int sum)
{
int i;
for(i=0;i<n;i++)
if(visited[i]==0&&E[x][i]!=0)
{
visited[i]=1;
T[i]=sum+E[x][i];
dfs(i,n,T[i]);
}
}
int main()
{
int m,n,a,k,b,i,j,num,sum,roota,rootb;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(i=0;i<n;i++)
{
T[i]=-1;
visited[i]=0;
}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
E[i][j]=0;
k=1;
for(i=0;i<m;i++)
{
scanf("%d %d",&a,&b);
roota=findroot(a);
rootb=findroot(b);
if(roota!=rootb)
{
T[rootb]=roota;
E[a][b]=k%M;
E[b][a]=k%M;
}
k=(k*2)%M;
}
i=0;
sum=0;
visited[0]=1;
for(i=1;i<n;i++)
T[i]=-1;
dfs(0,n,sum);
for(i=1;i<n;i++)
printf("%d\n",T[i]%M);
}
return 0;
}
由于第i条边的权值w[i] = 2^i,那么前i-1条边的权值之和为w[0]+w[1]+·+w[i-1] =(2^i)-1
也就是说前i-1条边的权值之和小于第i条边。
根据这一性质,当添加第i条边(a,b)时:
若a,b未连通,则a,b间的最短路径为w[i];
若a,b已经连通,则a,b之间的最短路径保持不变。
#include<cstdio>
#include<fstream>
using namespace std;
#define MAX 550
#define INF 9999999
#define M 100000
int father[MAX], rank[MAX];
int d[MAX][MAX];
void init ( int n )
{
for ( int i = 0; i < n; i++ )
{
father[i] = i;
rank[i] = 1;
d[i][i] = 0;
}
}
int Find ( int i )
{
if ( i != father[i] )
father[i] = Find(father[i]);
return father[i];
}
void Union ( int a, int b )
{
int ta = Find(a);
int tb = Find(b);
if ( ta == tb ) return;
if ( rank[a] >= rank[b] )
{
father[tb] = ta;
rank[ta] += rank[tb];
}
else
{
father[ta] = tb;
rank[tb] += rank[ta];
}
}
int mod_exp ( long long a, long long b )
{
long long ret = 1;
while ( b > 0 )
{
if ( b & 1 )
ret = ( ret * a ) % M;
b >>= 1;
a = ( a * a ) % M;
}
return ret;
}
int main()
{
int n, m, i, j, k;
int a, b, ta, tb, dist;
while ( scanf("%d%d",&n,&m) != EOF )
{
init(n);
for ( k = 0; k < m; k++ )
{
scanf("%d%d",&a,&b);
ta = Find(a);
tb = Find(b);
if ( ta == tb ) continue;
dist = mod_exp(2,k);
for ( i = 0; i < n; i++ )
{
if ( Find(i) != ta ) continue;
for ( j = 0; j < n; j++ )
{
if ( Find(j) != tb ) continue;
d[i][j] = (d[i][a] + dist + d[b][j]) % M;
d[j][i] = d[i][j];
}
}
Union(a,b);
}
ta = Find(0);
for ( i = 1; i < n; i++ )
{
if ( Find(i) == ta )
printf("%d\n",d[0][i]);
else printf("-1\n");
}
}
return 0;
}
相关文章推荐
- 1.1、回归之最小二乘法
- 第一周学习总结
- 百思学习笔记09-调整项目文件结构
- KMP算法笔记
- 1、机器学习之回归
- csu1023 修路(二分查找)
- e.preventDefault() e.stopPropagation()和return false的区别
- PHP->iNews新闻发布系统目录结构3
- 《Desperate Housewives/绝望的主妇》8段经典美句
- HYSBZ/BZOJ 1013 [JSOI2008] 球形空间产生器sphere - 高斯约当消元
- C++类成员函数做参数以及转换调用
- Codeforces AIM Tech Round (Div. 1)623A Graph and String
- Android 内核常见目录的作用
- Backbone.router
- Android 内核常见目录的作用
- Android 内核常见目录的作用
- 【Cocos2d-x源码分析】 UserDefault如何保存本地数据
- 0206-UITableView上的批量操作(自定义)
- Android 内核常见目录的作用
- 编程算法之常数变异法