圖論思想,DP構造求解

來源:互聯網
上載者:User

B-Travel By AirlineTime Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)Total Submission(s) : 24   Accepted Submission(s) : 1Font: Times New Roman | Verdana | GeorgiaFont Size: ← →Problem DescriptionYou have won a chance to travel around Canada by airline, beginning in the most western point served by this airline, then traveling only from west to east until you reach the most eastern point served, and then coming back only from east to west until you
reach the starting city. No city may be visited more than once, except for the starting city, which must be visited exactly twice (at the beginning and the end of the trip). You are not allowed to use any other airline or any other means of transportation.
Given a list of cities served by the airline and a list of direct flights between pairs of cities, find an itinerary which visits as many cities as possible and satisfies the above conditions beginning with the first city and visiting the last city on the list
and returning to the first city.InputThere are several test cases.
In each test case:
Line 1 : The number N (N <= 100) of cities , the number V (V>0) of direct flights that will be listed 
Line 2..N+1 : Each line contains a name of a city served by the airline.The names         are ordered from west to east in the input.
Lines N+2..N+2+V-1 : Each line contains two names of cities (taken from the supplied list), separated by a single blank space. This pair is connected by a direct, two-way airline flight.OutputThe number M of different cities visited in the optimal itinerary. Output 1 if no itinerary is possible.Sample Input
8 9Vancouver       Yellowknife EdmontonCalgaryWinnipegToronto MontrealHalifax Vancouver EdmontonVancouver Calgary Calgary WinnipegWinnipeg TorontoToronto HalifaxMontreal HalifaxEdmonton MontrealEdmonton YellowknifeEdmonton Calgary
Sample Output
7

這題比較特殊吧,本來認為是圖論題,構圖了很久想用最大流做,結果發現不行,構圖能力還不到家。關鍵是最東邊的城市一定要到達。也就是說,拆點來做的話,最東邊的城市這條關鍵邊十分難控制了。比如說,流向最東邊城市的話,還要返回,而且每個城市只能走一次,這樣狀態的影響就不是那麼輕易可以表達的了。眾所周知,網路流是用方向流量來擴流的。顯然將最東邊城市置於圖中心,雖能保證該城市一定被走到(如果能流到),但是E城的上下是有關聯的,也就是只走一次..這樣我就不能構圖了... 看了題解,用DP,直到A掉這題我才知道,為什麼能用DP,因為這題的限制很多,首先去E城市只能向E方向走,回來只能向W方向走。這確定了方向的一致性,符合DP的儲存狀態。而且這題的環路有特殊的解法,將回來的邊反向,這樣就可以看成是兩個人同時向終點進發,最後DP求解就是了。 另外要注意的就是DP的解釋f[i,N]中最大的且reach[i][N]==true; 題還不錯。
#include<iostream>#include<fstream>#include<map>#include<cstring>#include<string>using namespace std;bool reach[111][111];int max( int a,int b ){ return a>b?a:b; }int main(){ ifstream fin("2.in");ofstream fout("ans.out"); int n,m; string str1,str2; map<string,int>map; int cnt; while( fin>>n>>m ) {    memset( reach,0,sizeof(reach) );    map.clear();    cnt=0;    int f[111][111];    for( int i=1;i<=n;i++ )    {    fin>>str1;    map[str1]=i;   }   for( int i=1;i<=m;i++ )   {   fin>>str1>>str2;   reach[map[str1]][map[str2]]=true;   reach[map[str2]][map[str1]]=true;      }/*      for( int i=1;i<=n;i++ )      {      for( int j=1;j<=n;j++ )    printf( "%d",reach[i][j]==1?1:0 );   printf( "\n" );   }*/      memset( f,0,sizeof(f) );     f[1][1]=1;      for( int i=1;i<=n;i++ )      for( int j=i+1;j<=n;j++ )      for( int k=1;k<j;k++ )      {      if( reach[k][j]&&k<j&&f[i][k] ) f[j][i]=f[i][j]=max(f[i][k]+1,f[i][j]);   }      for( int i=1;i<=n;i++ )   {   for( int j=1;j<=n;j++ )    printf( "%d ",f[i][j] );   printf( "\n" );   }   getchar();   int ans=1;   for( int i=1;i<n;i++ )   if( reach[i][n] )   ans=max( f[i][n],ans );      fout<<ans<<endl;     //printf( "%d\n",ans );  } return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.