標籤:style blog http color os 資料 io for
題目連結:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1256
題目大意:
在另一個平行宇宙中,有一個神奇的國度名叫天朝。天朝一共有N個城市(標號分別為1, 2, …, N),M條道路,為了方便交通管制,天朝的M條道路都是單行道。 不久前天朝大選,小Q當選了天朝的總統。小Q家住在城市1,但天朝的辦公地點在城市N,於是為了便於工作,小Q決定舉家從城市1搬遷到城市N去居住。然而小Q驚奇的發現,現在並不存在從城市1出發到城市N路線。 但這點難題是無法阻擋天朝總統的,小Q決定行使總統的權利下令更改一些道路的通行方向,使得至少存在一條從城市1出發到城市N的路線,但為了節省時間和資源,他希望更改通行方向的道路儘可能少,你能幫幫小Q嗎? 輸入包含多組測試資料。 對於每組測試資料,第一行包含兩個正整數N (2<=N<=5000)、M (1<=M<=10000),表示天朝一共有N個城市、M條道路。接下來M行每行有兩個正整數u、v (1<=u, v<=N),表示城市u和城市v之間有一條通行方向為u->v的單行道。兩個城市之間可能有多條道路。 對於每組測試資料,用一行輸出一個整數表示最少需要更改多少條單行道的通行方向,才能使得至少存在一條路線能夠讓小Q從城市1出發到城市N。 如果沒辦法使得至少存在一條路線讓小Q從城市1出發到城市N,則輸出“-1”(不包括引號)。 思路是:在給出的路的條件下,都給它添加一條相反方向上的路,令其權值為1,而原方向的權值為0,因為每條路不可能走回頭路,所以將兩條路都放著,根據所需取哪條,那麼求所需修改的路的方向相當於在求1到N的最短路徑,找不到路徑說明路怎麼修改方向都沒用,輸出-1 這道題不同於前面,我將一條路上的對應的終點,長度以及同一起點對應的下一條路的位置用一個path的結構體儲存,這樣不會令數組太多而感覺很亂 代碼如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 #define N 5005 7 #define M 20010 8 #define MAXN 0x3f3f3f3f 9 int first[N],k,visit[N],dp[N];//對應i城市第一條道路的下標,k表示路的條數10 11 struct Path{12 int y,next,d;//y表示終點,next從同一起點出發對應的下一條路的下標,d表示路的長度13 }path[M];14 15 void add(int x,int y,int a){16 path[k].y=y,path[k].d=a,path[k].next=first[x];17 first[x]=k;18 k++;19 }20 21 void spfa(int a){22 memset(dp,0x3f,sizeof(dp));23 queue<int> q;24 dp[a]=0,visit[a]=1;25 q.push(a);26 while(!q.empty()){27 int b=q.front();28 q.pop();29 visit[b]=0;30 for(int i=first[b];i!=-1;i=path[i].next){31 if(dp[path[i].y]>dp[b]+path[i].d){32 dp[path[i].y]=dp[b]+path[i].d;33 if(!visit[path[i].y]) visit[path[i].y]=1,q.push(path[i].y);34 }35 }36 }37 }38 39 int main()40 {41 int n,m,u,v;42 while(scanf("%d%d",&n,&m)!=EOF){43 memset(first,-1,sizeof(first));44 k=0;45 for(int i=0;i<m;i++)46 {47 scanf("%d%d",&u,&v);48 add(u,v,0);49 add(v,u,1);50 }51 spfa(1);52 if(dp[n]<MAXN) cout<<dp[n]<<endl;53 else cout<<-1<<endl;54 }55 return 0;56 }