不錯的題目,由於只能從國度1到國度2一次,我原來想建兩張圖,一張都是國度1的點,另一張都是國度2的點,分別以城市1和城市2為源點求最短路徑再枚舉,後來看了別人的(承認這點不好,自己很少深入思考),只要一張圖就行了,做法就是把2到1的邊換成單向的,只能從1到2(因為一開始在1)
自己能夠想到一些東西,但是缺乏有效利用這些東西的能力,比如這道題的建圖方法,很巧妙,雖然基本的性質我知道,但就是想不到,可能是對題目意思和圖的理解的還不夠深入吧
代碼:
#include<iostream><br />using namespace std;<br />#define inf 999999<br />int g[605][605];<br />int dis[605],u[605],c[605];<br />void dijkstra(int source,int n)<br />{<br />int i,j,k,min;<br />memset(u,0,sizeof(u));<br />for(i=1;i<=n;i++)<br />dis[i]=inf;<br />dis[source]=0;<br />for(i=1;i<=n;i++)<br />{<br />min=inf;<br />for(j=1;j<=n;j++)<br />{<br />if(!u[j]&&dis[j]<min)<br />{<br />min=dis[j];<br />k=j;<br />}<br />}<br />u[k]=1;<br />for(j=1;j<=n;j++)<br />{<br />if(g[k][j])//如果存在邊<br />{<br />if(g[k][j]+dis[k]<dis[j])<br />{<br />dis[j]=g[k][j]+dis[k];<br />}<br />}<br />}<br />}<br />}<br />int main()<br />{<br />int i,j,k,n,m,a,b,t,w;<br />while(scanf("%d",&n)!=EOF&&n)<br />{<br />memset(g,0,sizeof(g));<br />memset(c,0,sizeof(c));<br />scanf("%d",&m);<br />for(i=1;i<=m;i++)<br />{<br />scanf("%d %d %d",&a,&b,&w);<br />g[a][b]=g[b][a]=w;<br />}<br />for(i=1;i<=n;i++)<br />scanf("%d",&c[i]);<br />for(i=1;i<=n;i++)<br />{<br />if(c[i]==2)<br />{<br />for(j=1;j<=n;j++)<br />{<br />if(c[j]==1)<br />g[i][j]=0;//刪除2到1的邊<br />}<br />}<br />}<br />dijkstra(1,n);<br />if(dis[2]==inf)<br />{<br />printf("-1/n");<br />}<br />else<br />printf("%d/n",dis[2]);<br />}<br />return 0;<br />}