程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> poj 1422 最小路徑覆蓋

poj 1422 最小路徑覆蓋

編輯:C++入門知識

題意:一個地圖上有n個小鎮,以及連接著其中兩個小鎮的有向邊,而且這些邊無法形成回路。現在選擇一些小鎮空降士兵(1個小鎮最多1個士兵),士兵能沿著邊走到盡頭,問最少空降幾個士兵,能遍歷完所有的小鎮。


思路:匈牙利算法求最小路徑覆蓋:在一個有向圖中,路徑覆蓋就是在圖中找一些路徑,使之覆蓋了圖中的所有頂點,且任何一個頂點有且只有一條路徑與之關聯;(如果把這些路徑中的每條路徑從它的起始點走到它的終點,那麼恰好可以經過圖中的每個頂點一次且僅一次);解決此類問題可以建立一個二分圖模型。把所有頂點i拆成兩個:X結點集中的i和Y結點集中的i',如果有邊i->j,則在二分圖中引入邊i->j',設二分圖最大匹配為m,則結果就是n-m

 

代碼:

[cpp]
<span style="font-family:KaiTi_GB2312;font-size:18px;">#include<iostream> 
using namespace std; 
const int maxn=125; 
int map[maxn][maxn],visit[maxn],match[maxn]; 
int n; 
bool dfs(int v) 

     int i; 
     for(i=1;i<=n;i++) 
     { 
       if(map[v][i]&&!visit[i]) 
       { 
          visit[i]=1; 
          if(match[i]==-1||dfs(match[i])) 
          { 
            match[i]=v; 
            return true; 
          } 
       } 
     } 
     return false; 

             
int hungry() 

    int i,ans=0; 
    memset(match,-1,sizeof(match)); 
    for(i=1;i<=n;i++) 
    { 
       memset(visit,0,sizeof(visit)); 
       if(dfs(i)) ans++; 
    } 
    return ans; 

        
     
int main() 

    int i,t,j,a,b,ans,m; 
    scanf("%d",&t); 
    while(t--) www.2cto.com
    { 
      scanf("%d%d",&n,&m); 
      memset(map,0,sizeof(map)); 
      for(i=0;i<m;i++) 
      { 
        scanf("%d%d",&a,&b); 
        map[a][b]=1; 
      } 
      ans=n-hungry(); 
      printf("%d%\n",ans); 
    } 
    return 0; 

       
</span> 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved