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

hust 1342 Cheat Secretly

編輯:C++入門知識

題目大意:一個人,如果在一人點沒有出邊時,可以跳轉到任意點,求最小跳轉次數使得走完所有必走邊。

題目思路:有上下界的最小流。

[cpp] 
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<string> 
#include<queue> 
#include<algorithm> 
#include<vector> 
#include<stack> 
#include<list> 
#include<iostream> 
#include<map> 
using namespace std; 
#define inf 0x3f3f3f3f 
#define Max 550 
int max(int a,int b) 

    return a>b?a:b; 

int min(int a,int b) 

    return a<b?a:b; 

int dis[Max],gap[Max],pre[Max],cur[Max],p[Max]; 
int in[Max],out[Max]; 
int n,m,s,t,eid; 
struct node 
 { 
     int to,next,c; 
 }e[40400],ee[40400]; 
void addedge(int u,int v,int c) 

    ee[eid].to=v; 
    ee[eid].c=c; 
    ee[eid].next=p[u]; 
    p[u]=eid++; 

int  ISAP(int st,int ed,int n,int count)   ///起點,終點,頂點數 

    memset(dis, 0, sizeof(dis)); 
    memset(gap, 0, sizeof(gap));  gap[0]=n; 
    memcpy(cur, p, sizeof(p));      ///memcpy! 
    int  i,flag,v,u=pre[st]=st,maxflow=0,aug=inf; //puts("akk"); 
    while(dis[st] < n) 
    { 
        for(flag=0,i=cur[u];i!=-1; i=e[i].next)  /// cur[u] 
            if(e[i].c&& dis[u] == dis[e[i].to]+1) 
            { 
                flag = 1; 
 
                break; 
            } 
        if(flag) 
        { 
            if(aug > e[i].c) 
                aug = e[i].c; 
            v = e[i].to; 
            pre[v] = u; 
            cur[u] = i; 
            u = v; 
            if(u == ed) 
            { 
                for(u=pre[u]; 1;u=pre[u])    ///notice! 
                { 
                    e[cur[u]].c -= aug; 
                    e[cur[u]^1].c += aug; 
                    if(u==st) break; 
                } 
                maxflow += aug; 
                aug = inf; 
            } 
        } 
        else 
        { 
            int minx = n; 
            for(i=p[u]; i!=-1; i=e[i].next) 
                if(e[i].c&& dis[e[i].to]<minx) 
                { 
                    minx = dis[e[i].to]; 
                    cur[u] = i; 
                } 
            if(--gap[dis[u]] == 0) 
                break; 
            dis[u] = minx+1; 
            gap[dis[u]]++; 
            u = pre[u]; 
        } 
    } 
    return maxflow; 

int main() 

    int m,n,t,count=1,sum; 
    int u,v,i,j,k,x,y,tp; 
    scanf("%d",&t); 
    while(t--) 
    { 
        scanf("%d%d",&n,&m); 
        memset(p,-1,sizeof(p)); 
        eid=0; 
        sum=0; 
        memset(in,0,sizeof(in)); 
        memset(out,0,sizeof(out)); 
        for(i=0;i<m;i++) 
        { 
            scanf("%d%d%d",&u,&v,&tp); 
            if(tp==1) 
            { 
                in[v]+=1; 
                sum+=1; 
                out[u]+=1; 
                addedge(u,v,inf-1); 
                addedge(v,u,0); 
            } 
            else 
            { 
                addedge(u,v,inf); 
                addedge(v,u,0); 
            } 
        } 
        for(i=1;i<=n;i++) 
        { 
            addedge(n+2,i,in[i]); 
            addedge(i,n+2,0); 
            addedge(i,n+3,out[i]); 
            addedge(n+3,i,0); 
            addedge(0,i,inf); 
            addedge(i,0,0); 
            if(out[i]==0) 
            { 
                addedge(i,n+1,inf); 
                addedge(n+1,i,0); 
            } 
        } 
        addedge(n+1,0,inf); 
        addedge(0,n+1,0); 
        int l,r,mid; 
        l=0;r=sum+2; 
        while(l<=r) 
        { 
            mid=(l+r)>>1; 
            for(i=0;i<=eid;i++)  e[i]=ee[i]; 
            e[p[n+1]].c=mid; 
            e[p[0]].c=0; 
            if(ISAP(n+2,n+3,n+4,count)==sum) 
                r=mid-1; 
            else 
                l=mid+1; 
        } 
            printf("Case #%d: %d\n",count++,l); 
    } 

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