misschuer

常用链接

统计

积分与排名

百事通

最新评论

poj 3189 Steady Cow Assignment

//题意 貌似是求满意度的范围最小.
//顺便贴个以前找到的, 效率还算可以的最大流模板

#include 
<cstdio>
#include 
<iostream>
#include 
<cstring>
using namespace std;
const int MAXV = 1210;
const int MAXE = 1000010;
const int inf = 1 << 29;

int head[MAXV], N;

struct Edge {
    
    
int v, next, w;
}edge[MAXE];

int n, m, s, t, cnt, ans;

void add(int u, int v, int w) {
    
    edge[cnt].v 
= v;
    edge[cnt].w 
= w;
    edge[cnt].next 
= head[ u ];
    head[ u ] 
= cnt++;
    
    edge[cnt].v 
= u;
    edge[cnt].w 
= 0;
    edge[cnt].next 
= head[ v ];
    head[ v ] 
= cnt++;
}

int sap() {
    
    
int pre[MAXV], cur[MAXV], dis[MAXV], gap[MAXV];
    
int flow = 0, aug = inf, u;
    
bool flag;
    
    
for(int i = 0; i <= N; ++ i) {
        
        cur[ i ] 
= head[ i ];
        gap[ i ] 
= dis[ i ] = 0;
    }
    
    gap[ s ] 
= N;
    u 
= pre[ s ] = s;
    
    
while(dis[ s ] < N) {
        
        flag 
= 0;
        
        
for(int &= cur[ u ]; j != -1; j = edge[ j ].next) {
            
            
int v = edge[ j ].v;
            
            
if(edge[ j ].w > 0 && dis[ u ] == dis[ v ] + 1) {
                
                flag 
= 1;
                
                
if(edge[ j ].w < aug) aug = edge[ j ].w;
                
                pre[ v ] 
= u;
                u 
= v;
                
                
if(u == t) {
                    
                    flow 
+= aug;
                    
                    
while(u != s) {
                        
                        u 
= pre[ u ];
                        edge[cur[ u ]  ].w 
-= aug;
                        edge[cur[ u ]
^1].w += aug;
                    }
                    aug 
= inf;
                }
                
break;
            }
        }
        
        
if(flag) continue;
        
        
int mindis = N;
        
        
for(int k = head[ u ]; k != -1; k = edge[ k ].next) {
            
            
int v = edge[ k ].v;
            
            
if(edge[ k ].w > 0 && dis[ v ] < mindis) {
                
                mindis 
= dis[ v ];
                cur[ u ] 
= k;
            }
        }
        
        
if( (--gap[dis[ u ]]) == 0break;
        
        dis[ u ] 
= mindis + 1;
        gap[dis[ u ]] 
++;
        u 
= pre[ u ];
    }
    
return flow;
}

int cap[30], i, j;
int mat[MAXV][30];

int main() {
    
    
while(scanf("%d %d"&m, &n) != EOF) {
        
        
for(i = 1; i <= m; ++ i) {
            
            
for(j = 1; j <= n; ++ j) {
                
                scanf(
"%d"&mat[ i ][ j ]);
            }
        }
        
        
for(i = 1; i <= n; ++ i) {
            
            scanf(
"%d"&cap[ i ]);
        }
        
        
int left = 1, right = 1int mmax = n;
        
        
while(left <= n && right <= n) {
            
            
            s 
= 0; t = m + n + 1; cnt = 0; N = t + 1;
            memset(head,
-1,sizeof(head));
            
            
for(i = 1; i <= m; ++ i) {
                
                add(s, i, 
1);
            }
            
            
for(i = 1; i <= m; ++ i) {
                
                
for(j = 1; j <= n; ++ j) {
                    
                    
if(left <= j && j <= right) {
                        
                        add(i, mat[ i ][ j ]
+m, 1);
                    }
                }
            }
            
            
for(j = 1; j <= n; ++ j) {
                
                add(m
+j, t, cap[ j ]);
            }
            
            ans 
= sap();
            
            
if(ans == m) {
                
                
if(mmax > right - left + 1) mmax = right - left + 1;
                left 
++;
            }
            
else right ++;
        }
        
        printf(
"%d\n", mmax);
    }
    
return 0;
}

posted on 2011-03-24 11:05 此最相思 阅读(133) 评论(0)  编辑 收藏 引用


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