2009-07-16 18:58:38來源不明

94全國資訊學科能力決賽 1. 城市道路連通網

作法:DP (有點像是Floyd-Warshall)

來源取自:JoyBO大大所編寫的 連結

題目說明:
給你n個城市的無向圖,請輸出起始點(start)到目的點(end)之間距離不超過len的走法有幾種。

心得:原本用DFS可是會TLE,最後找出DP的規則,假設要從城市A→城市B,就開始建表,先找到是否有城市C→城市B,那在把城市A連結(城市C→城市B),這樣就從距離1變成距離2,最後再把所有的距離1~len的走法加總起來就是答案。

在此提供 AC的DP(第1) 跟 TLE的DFS(第2)

/***********************************************************/

#include<stdio.h>  
#include<stdlib.h>  
int map[33][33]={0};  
int m,k,a,b,c,start,end,N;  
main()  
{  
 while(scanf("%d",&m)==1)  
  {  
   char x[50];  
   int DP[52][33][33]={0};  
   for(a=0;a<m;a++)  
    {  
      scanf("%s",x);  
      for(b=0;b<m;b++)  
       {  
         map[a][b]=x[b]-48;   
         DP[1][a][b]=x[b]-48;  
       }  
    }   
    scanf("%d %d %d",&start,&end,&N);   
    start--;end--;  
    for(k=1;k<=N;k++)  
       for(a=0;a<m;a++)  
          for(b=0;b<m;b++)  
             for(c=0;c<m;c++)  
                if(map[a][c]==1)   /*如果A跟C有相連 則將C →B 的走法加上去 變成C →B →A 就會變成 K 步*/ 
                    DP[k][a][b]=DP[k][a][b]+DP[k-1][c][b];  
    int ans=0;  
    for(a=1;a<=N;a++)  
       ans+=DP[a][start][end];  
    printf("%d\n",ans);   
  }   
 return 0;  
}

/************************************************************/

/**********************************************************************************/
/*  Problem: b062 "1. 城市道路連通網" from 94全國資訊學科能力決賽*/
/*  Language: C                                                                   */
/*  Result: WA (line:4) on ZeroJudge                                              */
/*  Author: morris1028 at 2009-07-16 14:33:30                                     */
/**********************************************************************************/

#include<stdio.h>
#include<stdlib.h>
int map[33][33]={0};
int m,a,b,c,ans,start,end,N;
void DFS(int now,int walk)
{
 if(walk>N) return;
 else
   {
     int a;
     if(now==end) {ans++;}
     for(a=1;a<=m;a++)
      if(map[now][a]==1)
       DFS(a,walk+1);
   }
}
main()
{
 while(scanf("%d",&m)==1)
  {
   char x[50];
   for(a=1;a<=m;a++)
    {
      scanf("%s",x);
      for(b=0;b<m;b++)
       map[a][b+1]=x[b]-48;
    }
    ans=0;
    scanf("%d %d %d",&start,&end,&N);
    if(m>20) break;
    DFS(start,0);
    printf("%d\n",ans);
  }
 return 0;
}