beloved_ACM

SB,NB,都是一个B.
posts - 29, comments - 2, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

太空飞行计划

Posted on 2010-10-02 22:20 成幸毅 阅读(219) 评论(0)  编辑 收藏 引用
实际上就是求最大权闭合图,还是比较容易的,没OJ交,就过了下样例。
#include <iostream>
#include 
<queue>
using namespace std;
const int MAXN = 500;
const int INF = 0x3fffffff;
int n,m;
int s,t;
int d[MAXN]; 
int pre[MAXN];
int num[MAXN];
int exp[MAXN];
int instr[MAXN];
int cnt[MAXN];
int c[MAXN][MAXN];

void ini_d(int s,int t) {
   
   memset(d,INF,
sizeof(d));
   memset(num,
0,sizeof(num));
   queue
<int> Q;
   Q.push(t);
   d[t] 
= 0;
   num[
0= 1;
   
int k ;
   
while(!Q.empty()) {
      k 
= Q.front();Q.pop();
      
for(int i = 0; i <= t ; i++{
         
if(c[i][k] > 0 && d[i] > t) {
            d[i] 
= d[k] + 1;
            Q.push(i);
            num[d[i]]
++;
         }

      }

   }

}


int findAlowArc(int i) {
   
int j;
   
for(j = 0; j < t + 1; j++{
      
if(c[i][j] > 0 && d[i] == d[j] + 1{
         
return j;
      }

   }

   
return -1;
}


int reLable(int i) {
   
int j;
   
int mm = INF;
   
for(j = 0; j < t +1; j++{
      
if(c[i][j] > 0) mm = min(mm,d[j] + 1); 
   }

   
return mm == INF?t+1:mm;
}


int maxFlow(int s,int t) {
     
    ini_d(s,t);
    
int flow = 0,i = s,j;
    
int delta;
    memset(pre,
-1,sizeof(pre));
    
    
while(d[s] <= t) {
        
        j 
= findAlowArc(i);
        
if(j >= 0{
           pre[j] 
= i;
           i 
= j;
           
if(i == t) {
               delta 
= INF;
               
for(i = t; i != s; i = pre[i]) delta = min(delta,c[pre[i]][i]);
               
for(i = t; i != s; i = pre[i]) 
                  c[pre[i]][i] 
-= delta,c[i][pre[i]] += delta;
                  flow 
+= delta;
           }

        }

        
else {
           
int x = reLable(i);
           num[x]
++;
           num[d[i]]
--;
           
if(num[d[i]] == 0return flow;
           d[i] 
= x;
           
if(i != s) i = pre[i];
        }

    }

    
return flow;
    
}


void dfs(int i) {
   
   
   cnt[i] 
= 1;
   
for(int j = 0; j < t+1; j++{
      
if(c[i][j] > 0 && !cnt[j]) {
         dfs(j);
      }

   }

}


int main() {
   
   
while(scanf("%d%d",&n,&m) != EOF) {
      
int sum = 0;
      
int cost,u,v;
      s 
= 0; t = n + m + 1;
      memset(c,
0,sizeof(c));
      memset(exp,
0,sizeof(exp));
      memset(instr,
0,sizeof(instr));
      memset(cnt,
0,sizeof(cnt));
      
for(int i = 1; i <= n; i++{
         scanf(
"%d%d%d",&cost,&u,&v);
         sum 
+= cost;
         c[s][i] 
= cost;
         c[i][u
+n] = c[i][v+n] = INF;
         exp[i] 
= 1;
         instr[u] 
= instr[v]  = 1;
      }

      
      
for(int i = n+1; i <= m+n; i++{
         scanf(
"%d",&cost);
         c[i][t] 
= cost;
      }

      
int ans = maxFlow(s,t);
      dfs(
0);
      
for(int i = 1; i < t + 1; i++{
         
if(cnt[i] == 1
           
if(exp[i]) 
             printf(
"%d ",i);
      }

      cout
<<endl;
       
for(int i = 1; i < t + 1; i++{
         
if(cnt[i] == 1
           
if(instr[i]) 
             printf(
"%d ",i);
      }

      cout
<<endl;
      printf(
"%d\n",sum - ans);
      
   }

   system(
"pause");
   
return 0;
}


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理