luogu P2402 奶牛隱藏

2021-08-20 03:49:16 字數 1718 閱讀 5367

題目傳送門:

題意:

有n個點,m條邊,每乙個點一開始都有b1i頭奶牛,並且都可以容納b2i頭奶牛,但是b1i有可能大於b2i,因此奶牛需要遷徙,遷徙的時間為路程的長度。求最小的時間,若無法完成,輸出-1。

思路:

容易想到最短路floyd,因為可以與處理出從i點到j點的最短路(即時間花費)。

然後發現時間好像不能直接求,它具有單調性,再來個二分時間mid,若當前時間允許,則找更短的耗時,否則找更長的耗時。

最後發現可以用網路流求解,就是讓不同的牛移動。

構圖:

必然要拆點。

[1]源點向每乙個點連一條流量為b1i

的邊,表示一開始這裡有b1i

頭奶牛;

[2]每乙個點向匯點連一條流量為b2i的邊,表示最多能容納b2i頭奶牛;

[3]每乙個點的入點向出點連一條流量為inf的邊表示可以有無數頭奶牛在這裡中轉;

[4]每乙個點它能去到的點的最短路(即時間花費)小於等於二分的時間mid,則連一條流量為inf

的邊,表示從i點到j點在規定時間裡可以有無數頭奶牛走過。

有解的情況是flow=sum(b1的總和,即總的奶牛數),此時保證每一頭奶牛都有乙個被容納的點,且每乙個點都沒有超過它的容量。

**:

#include#include#include#include#define inf 1e18

#define ll long long

#define max(x,y) ((x)>(y)?(x):(y))

#define min(x,y) ((x)<(y)?(x):(y))

using namespace std;

queuef;

struct node a[100010];

int b1[500],b2[500],last[1000];

ll map[300][300];

int n,m,len=-1,st,ed;

ll s=0,ans=-1;

void ins(int x,int y,ll z)

int h[1000];

bool bfs()

} f.pop();

} if(h[ed]) return true; else return false;

}ll dfs(int x,ll f)

} if(!s) h[x]=0;

return s;

}ll dinic()

ll work(ll x)

return dinic();

} int main()

for(int i=1;i<=n;i++)

for(int j=1;j<=n;j++)

map[i][j]=i==j?0:inf;

for(int i=1;i<=m;i++)

for(int k=1;k<=n;k++)

for(int i=1;i<=n;i++)

for(int j=1;j<=n;j++)

map[i][j]=min(map[i][j],map[i][k]+map[k][j]),r=max(r,map[i][j]);

while(l<=r)

printf("%lld",ans);

}

luogu2402 奶牛隱藏

在乙個農場裡有n塊田地。某天下午,有一群牛在田地裡吃草,他們分散在農場的諸多田地上,農場由m條無向的路連線,每條路有不同的長度。突然,天降大雨,奶牛們非常混亂,想要快點去躲雨。已知每個田地都建立有乙個牛棚,但是每個牛棚只能容納一定數量的牛躲雨,如果超過這個數量,那多出的牛只能去別的田地躲雨。奶牛們每...

題解 奶牛隱藏

可以想到把奶牛當做水流,從最初奶牛在的節點,流到他最後停下的節點。但是時間不容易在圖上體現出來,考慮二分這個時間 這是網路流常見套路 然後判定在這個時間內,所有奶牛能否流到匯點。對於建圖,首先是對源點向每個點建一條邊,容量為這個點初始的奶牛數,每個點向匯點連一條邊,容量為這個點最多容納奶牛的數量。至...

luogu P2619 奶牛工資

原題位置 這道題是個貪心,怎麼說是貪心呢,就是先選大的,後考慮小的 千萬不要把上句話的意思理解歪了,一開始我就理解歪了,然後華麗麗地tle了 其實就是for,然後如果當前這個值可以被選,就選到不能再選這個值為止 還有乙個小技巧,就是我們定義乙個值,等於c,然後用這個值減,知道小於等於0,這樣子比一直...