1. 程式人生 > >暢通project續

暢通project續

寫法 mono otto con clas turn esc project input

Time Limit : 3000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)

Total Submission(s) : 36 Accepted Submission(s) : 25
Problem Description 某省自從實行了非常多年的暢通project計劃後,最終修建了非常多路。只是路多了也不好,每次要從一個城鎮到還有一個城鎮時,都有很多種道路方案能夠選擇,而某些方案要比還有一些方案行走的距離要短非常多。這讓行人非常困擾。

如今,已知起點和終點。請你計算出要從起點到終點,最短須要行走多少距離。


Input 本題目包括多組數據,請處理到文件結束。每組數據第一行包括兩個正整數N和M(0<n<200,0<m<1000),分別代表現有城鎮的數目和已修建的道路的數目。

城鎮分別以0~n-1編號。 再接下一行有兩個整數s,t(0<="S,T<N),分別代表起點和終點。

</div" 接下來是m行道路信息。

每一行有三個整數a,b,x(0<="A,B<N,A!=B,0<X<10000),表示城鎮A和城鎮B之間有一條長度為X的雙向道路。">


Output 對於每組數據。請在一行裏輸出最短須要行走的距離。

假設不存在從S到T的路線,就輸出-1.


Sample Input
3 3
0 1 1
0 2 3
1 2 1
0 2
3 1
0 1 1
1 2

Sample Output
2
-1


#include<stdio.h>
#include<string.h>
#define min(a,b) (a)>(b)?(b):(a)
#define INL 10000000
int x[202][202];
int s[202],d[202];
int n,m,q,r;
void Dijkstra()
{
	int min,k;
	//for(int i=1;i<=n;i++)
	memset(s,0,sizeof(s));
	for(int i=0;i<n;i++)
		d[i]=INL;
    d[q]=0;
   while(1)
	{
	   
		k=-1;
		for(int j=0;j<n;j++)
		if(s[j]==0&&(k==-1||d[j]<d[k]))
		k=j;
		if(k==-1)
		{
			break;
		}
		s[k]=1;
		for(int j=0;j<n;j++)
		d[j]=min(d[j],d[k]+x[k][j]);
	}
	if(d[r]==INL)
	printf("-1\n");
	else
    	printf("%d\n",d[r]);
}
int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)//錯寫成<span style="font-family: Arial, Helvetica, sans-serif;">while(scanf("%d%d",&n,&m),n|m)</span>
	{
		int a,b,c,i,j;
	    for( i=0;i<n;i++)
	    for( j=0;j<n;j++)
	    x[i][j]=INL;
		for(i=0;i<m;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			if(x[a][b]>c)
			{
				x[a][b]=c;
			x[b][a]=c;
			} 
		}
		scanf("%d%d",&q,&r);
		Dijkstra();	
	}
	return 0;
}

再貼一個
#include<stdio.h>  
#include<string.h>
#define M  10000000
#define min(a,b) (a)>(b)?(b):(a)
int map[202][202];
int vis[202],dist[202];
int n,s,t;
void dijkstra()
{
    int min,i,j,k;
    memset(vis,0,sizeof(vis));
    for(i=0; i<n; i++)
        dist[i]=map[s][i];
    dist[s]=0;
   while(1)
    {
        min=M;
        for(j=0; j<n; j++)
            if(!vis[j]&&dist[j]<min)
            {
                min=dist[j];
                k=j;
            }
        if(min==M)break;
        vis[k]=1;
        for(j=0; j<n; j++)
        dist[j]=min(dist[j],dist[k]+map[k][j]);
    }
    if(dist[t]==M)
        printf("-1\n");
    else
        printf("%d\n",dist[t]);
}
int main()
{
    int i,j,x,y,z,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0; i<n; i++)
            for(j=0; j<n; j++)
                map[i][j]=M;

        for(i=0; i<m; i++)
        {
            scanf("%d%d%d",&x,&y,&z);

            if(map[x][y]>z)
            {
                map[y][x]=z;
                map[x][y]=z;
            }
        }
        scanf("%d%d",&s,&t);
        dijkstra();
    }
    return 0;
}
 

再貼一個用spfa算法寫的。
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct stu{
	int one,two,val,next;
};
stu edge[30000];
int N,M,d,f;
int head[30000],t,vid[300],dist[300];
void spfa(int s)
{
     queue<int> Q;
	 memset(dist,0x3f3f3f,sizeof(dist));//這個地方出錯了錯寫成 memset(dist,1000000,sizeof(dist));
	 memset(vid,0,sizeof(vid));
	 Q.push(s);
	 dist[s]=0;
	 vid[s]=1;
	 while(!Q.empty())
	 {
	   int	u=Q.front();
	 	Q.pop();
	 	vid[u]=0;
	 	for(int i=head[u];i!=-1;i=edge[i].next)
	 	{
	 		int v=edge[i].two;
	 		if(dist[v]>dist[u]+edge[i].val)
	 		{
	 			dist[v]=dist[u]+edge[i].val;
	 			if(!vid[v])
	 			{
				 	vid[v]=1;
	 				Q.push(v);
	 			}
	 		}
	 	}
	 }
	 if(dist[f]>1000000)
	 printf("-1\n");
	 else 
	 printf("%d\n",dist[f]);
}
void get(int a,int b,int c)
{
	stu E={a,b,c,head[a]};
	edge[t]=E;
	head[a]=t++;
}
int main()
{
	while(scanf("%d%d",&N,&M)!=EOF)
	{
		t=0;
		memset(head,-1,sizeof(head));
		int a,b,c;
		while(M--)
		{
			scanf("%d%d%d",&a,&b,&c);
			get(a,b,c),get(b,a,c);
		}
		scanf("%d%d",&d,&f);
		spfa(d);
	}
	return 0;
}

再貼一個spfa算法寫的代碼:
#include<stdio.h>
#include<string.h>
#include<queue>
#define INL 0x3f3f3f3f//有時候寫成0x3f3f3f時會出錯再加一個3f就正確了。
#include<algorithm>
using namespace std;
struct stu{
	int one,two,val,next;
};
stu edge[30000];
int head[30000],t,he,vid[300],vist[300];
void get(int u,int v,int w)
{
	stu E={u,v,w,head[u]};
	edge[t]=E;
	head[u]=t++;
}
void SPFA(int s)
{
	queue<int> q;
	memset(vist,INL,sizeof(vist));
	memset(vid,0,sizeof(vid));
	q.push(s);
	vist[s]=0;
	vid[s]=1;//這個地方錯寫成vid[s]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		vid[u]=0;//敲代碼時這個地方漏掉了
		for(int i=head[u];i!=-1;i=edge[i].next)
		{
			int v=edge[i].two;
			if(vist[v]>vist[u]+edge[i].val)
			{
				vist[v]=vist[u]+edge[i].val;
				if(!vid[v])
				{
					q.push(v);
					vid[v]=1;
				}
			}
		}
	}
	if(vist[he]==INL)//還有一種寫法if(vist[he]>100000)
	printf("-1\n");
	else
	printf("%d\n",vist[he]);
}
int main()
{
	int n,m;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		t=0;
		int i,j,k,a,b,c;
		memset(head,-1,sizeof(head));//這個出錯了
		for(i=0;i<m;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			get(a,b,c);
			get(b,a,c);
		}
		scanf("%d%d",&a,&he);
		SPFA(a);
	}
	return 0;
}




暢通project續