日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ 3228 二分最大流

發(fā)布時間:2025/6/17 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ 3228 二分最大流 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題意:
????? 給你N個位置,每個位置都有金礦數(shù)量和倉庫數(shù)量,然后位置和位置之間的距離給了出來,最后問你吧所有的金礦都放到庫里面走的路徑 最長的最短 是多少?

思路:
???? 比較簡單的一個題,直接二分答案,然后用最大流是否滿流來判斷二分方向,還有就是建圖的時候不用拆點什么的,一開始建圖想麻煩了,都快敲完了才反應(yīng)過來,具體看代碼。

?

?


#include<stdio.h>
#include<string.h>
#include<queue>

#define N_node 200? + 10
#define N_edge 90000
#define INF 1000000000

using namespace std;

typedef struct
{
?? int to ,cost ,next;
}STAR;

typedef struct
{
?? int x ,t;
}DEP;

typedef struct
{
?? int a ,b ,c;
}EDGE;

EDGE edge[22000];
STAR E[N_edge];
DEP xin ,tou;
int list[N_node] ,list2[N_node] ,tot;
int deep[N_node];
int aaa[220] ,bbb[220];

void add(int a ,int b ,int c)
{
???? E[++tot].to = b;
???? E[tot].cost = c;
???? E[tot].next = list[a];
???? list[a] = tot;
????
???? E[++tot].to = a;
???? E[tot].cost = c;
???? E[tot].next = list[b];
???? list[b] = tot;
}

bool BFS_Deep(int s ,int t ,int n)
{
?? memset(deep ,255 ,sizeof(deep));
?? xin.x = s ,xin.t = 0;
?? deep[xin.x] = xin.t;
?? queue<DEP>q;
?? q.push(xin);
?? while(!q.empty())
?? {
????? tou = q.front();
????? q.pop();
????? for(int k = list[tou.x] ;k ;k = E[k].next)
????? {
????????? xin.x = E[k].to;
????????? xin.t = tou.t + 1;
????????? if(deep[xin.x] != -1 || !E[k].cost)
????????? continue;
????????? deep[xin.x] = xin.t;
????????? q.push(xin);
????? }
?? }
?? for(int i = 0 ;i <= n ;i ++)
?? list2[i] = list[i];
?? return deep[t] != -1;
}

int minn(int x ,int y)
{
?? return x < y ? x : y;
}

int DFS_Flow(int s ,int t ,int flow)
{
?? if(s == t) return flow;
?? int nowflow = 0;
?? for(int k = list2[s] ;k ;k = E[k].next)
?? {
?????? list2[s] = k;
?????? int to = E[k].to;
?????? if(deep[to] != deep[s] + 1 || !E[k].cost)
?????? continue;
?????? int tmp = DFS_Flow(to ,t ,minn(E[k].cost ,flow - nowflow));
?????? nowflow += tmp;
?????? E[k].cost -= tmp;
?????? E[k^1].cost += tmp;
?????? if(nowflow == flow) break;
?? }
?? if(!nowflow) deep[s] = 0;
?? return nowflow;
}

int DINIC(int s ,int t ,int n)
{
?? int Ans = 0;
?? while(BFS_Deep(s ,t ,n))
?? {
?????? Ans += DFS_Flow(s ,t ,INF);
?? }
?? return Ans;
}

bool ok(int n ,int m ,int sum ,int mid)
{
???? memset(list ,0 ,sizeof(list)) ,tot = 1;
???? for(int i = 1 ;i <= n ;i ++)
???? {
??????? add(0 ,i ,aaa[i]);
??????? add(i ,n + 1 ,bbb[i]);
???? }
???? for(int i = 1 ;i <= m ;i ++)
???? if(edge[i].c <= mid)
???? {
??????? add(edge[i].a ,edge[i].b ,INF);
???? }
???? int flow = DINIC(0 ,n + 1 ,n + 1);
???? return? flow == sum;
}
????
int main ()
{
??? int n ,m ,i ,sum;
??? while(~scanf("%d" ,&n) && n)
??? {
??????? for(sum = 0 ,i = 1 ;i <= n ;i ++)
??????? {
?????????? scanf("%d" ,&aaa[i]);
?????????? sum += aaa[i];
??????? }
??????? for(i = 1 ;i <= n ;i ++)
??????? scanf("%d" ,&bbb[i]);
??????? scanf("%d" ,&m);
??????? for(i = 1 ;i <= m ;i ++)
??????? scanf("%d %d %d" ,&edge[i].a ,&edge[i].b ,&edge[i].c);
??????? int low ,up ,mid ,Ans = -1;
??????? low = 0 ,up = 11000;
??????? while(low <= up)
??????? {
?????????? mid = (low + up) >> 1;
?????????? if(ok(n ,m ,sum ,mid))
?????????? {
?????????????? Ans = mid;
?????????????? up = mid - 1;
?????????? }
?????????? else low = mid + 1;
??????? }
??????? Ans == -1 ? puts("No Solution"):printf("%d\n" ,Ans);
??? }
??? return 0;
}
???????

?

?

???????
???????

?

總結(jié)

以上是生活随笔為你收集整理的POJ 3228 二分最大流的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。