游客 Signup | Login
中文 | En

1525 - 最短路径2

N个城市,标号从0到N-1,M条道路,第K条道路(K从0开始)的长度为2^K,求编号为0的城市到其他城市的最短距离。

Input

第一行两个正整数N(2<=N<=100)M(M<=500),表示有N个城市,M条道路,

接下来M行两个整数,表示相连的两个城市的编号。

Output

N-1行,表示0号城市到其他城市的最短路,如果无法到达,输出-1,数值太大的以MOD 100000 的结果输出。

Examples

Input

4 3
0 1
1 2
2 0

Output

1
3
-1

Solution C

#include<stdio.h>

const int inf=1000000000;
const int mod=100000;
int p[101],rank[101],d[101][101];

int Find(int i)
{
	if(i==p[i])
		return i;
	else {
		p[i]=Find(p[i]);
        return  p[i];
	}
}

void Union(int a,int b)
{
        int ta=Find(a),tb=Find(b);
        if(ta==tb)
                return;
        if(rank[a]>=rank[b])
        {
                p[tb]=ta;
                rank[ta]+=rank[tb];
        }
        else
        {
                p[ta]=tb;
                rank[tb]+=rank[ta];
        }
}

int Pow( long a,long b)
{
        long  ret=1;
        while(b>0)
        {
                if(b&1)
                        ret=(ret*a)%mod;
                b>>=1;
                a=(a*a)%mod;
        }
        return ret;
}

int main()
{
        int n,m,i,j,k,a,b,ta,tb,dist;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
                for(i=0;i<n;i++)
                {
                        p[i]=i;
                        rank[i]=1;
                        d[i][i]=0;
                }
                for(k=0;k<m;k++)
                {
                        scanf("%d%d",&a,&b);
                        ta=Find(a);
                        tb=Find(b);
                        if(ta==tb)
                                continue;
                        dist=Pow(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])%mod;
                                        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;
}

Solution C++

#include<stdio.h>

const int inf=1000000000;
const int mod=100000;
int p[101],rank[101],d[101][101];

int Find(int i)
{
	return i==p[i]?i:p[i]=Find(p[i]);
}

void Union(int a,int b)
{
	int ta=Find(a),tb=Find(b);
	if(ta==tb)
		return;
	if(rank[a]>=rank[b])
	{
		p[tb]=ta;
		rank[ta]+=rank[tb];
	}
	else
	{
		p[ta]=tb;
		rank[tb]+=rank[ta];
	}
}

int Pow(long long a,long long b)
{
	long long ret=1;
	while(b>0)
	{
		if(b&1)
			ret=(ret*a)%mod;
		b>>=1;
		a=(a*a)%mod;
	}
	return ret;
}

int main()
{
	int n,m,i,j,k,a,b,ta,tb,dist;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		for(i=0;i<n;i++)
		{
			p[i]=i;
			rank[i]=1;
			d[i][i]=0;
		}
		for(k=0;k<m;k++)
		{
			scanf("%d%d",&a,&b);
			ta=Find(a);
			tb=Find(b);
			if(ta==tb)
				continue;
			dist=Pow(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])%mod;
					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;
}
Time Limit 1 second
Memory Limit 32 MB
Discuss Stats
上一题 下一题