题目链接:http://poj.org/problem?id=2391

今天掉坑多次。

做了几道题,发现从源点出来的边和进入汇点的边都在题目中出来过。

POJ真是坑,交G++一直wa,检查代码检查了好几遍,无望看discuss,才知道交C++是RE,才知道数组越界了。

手写了Floyd,写成 i,j,k,wa了,突然想到以前遇到过这种问题。

看昂神解释明白了。

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#include <queue>
using namespace std;
#define next Next
const int inf = 0x3f3f3f3f;
const int maxn=;
int level[maxn];
int iter[maxn];
int head[maxn],tot;
struct edge{
int to,cap,Next;
} e[]; ///此处应为边的两倍,加一条容量为0的反向边
void init(){
memset(head,-,sizeof(head));
tot=;
}
void add(int from,int to,int cap){
e[tot].Next=head[from];
e[tot].to=to;
e[tot].cap=cap;
head[from]=tot;
tot++;
}
void addedge(int from,int to,int cap){
add(from,to,cap);
add(to,from,);
}
void bfs(int s){
memset(level,-,sizeof(level));
queue<int> q;
level[s]=;
q.push(s);
while(!q.empty()){
int v=q.front(); q.pop();
for(int i=head[v];~i;i=e[i].Next){
edge &ed=e[i];
if(ed.cap>&&level[ed.to]<){
level[ed.to]=level[v]+;
q.push(ed.to);
}
}
}
}
int dfs(int v,int t,int f){
if(v==t) return f;
for(int &i=iter[v];~i;i=e[i].Next){
edge &ed=e[i];
if(ed.cap>&&level[v]<level[ed.to]){
int d=dfs(ed.to,t,min(f,ed.cap));
if(d>){
ed.cap-=d;
e[i^].cap+=d;
return d;
}
}
}
return ;
}
int max_flow(int s,int t){
int flow=;
while(){
bfs(s);
if(level[t]<) return flow;
memcpy(iter,head,sizeof(iter));
int f;
while((f=dfs(s,t,inf))>){
flow+=f;
}
}
}
int niu[maxn],capacity[maxn];
typedef long long ll;
ll dp[maxn][maxn];
void floyd(int n)
{
for(int k=;k<=n;k++)
{
for(int i=;i<=n;i++)
{
//if(i==j) continue;
for(int j=;j<=n;j++)
{
if(i==k||j==k||i==j) continue;
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k][j]);
}
}
}
}
int f,p;
void cons(ll T,int s,int t)
{
init();
for(int i=;i<=f;i++)
{
addedge(s,i,niu[i]);
addedge(i,i+f,inf);
addedge(i+f,t,capacity[i]);
}
for(int i=;i<=f;i++)
{
for(int j=;j<=f;j++)
{
if(i==j) continue;
if(dp[i][j]<=T)
{
addedge(i,j+f,inf);
}
}
}
}
int main()
{
int sum = ;
scanf("%d %d",&f,&p);
for(int i=;i<=f;i++)
{
scanf("%d %d",&niu[i],&capacity[i]);
sum += niu[i];
}
for(int i=;i<=f;i++)
{
for(int j=;j<=f;j++)
{
dp[i][j] = 1e15;
}
}
for(int i=;i<=p;i++)
{
int x,y;
ll w;
scanf("%d %d %lld",&x,&y,&w);
dp[x][y] = min(dp[x][y],w); ///一定要注意两点之间的有多条边的情况
dp[y][x] = dp[x][y];
}
floyd(f);
ll l = ,r = 2000000000000LL;
ll mid = ;
int s,t;
s = ,t = ; ///s,t一定要在head数组范围内
int flow = ;
ll ans = ;
while(l<=r)
{
mid = (l+r)/2LL;
cons(mid,s,t);
flow = max_flow(s,t);
// printf("%lld %d\n",mid,flow);
if(flow==sum)
{
ans = mid;
r = mid-;
}
else
{
l = mid+;
}
}
if(ans==)
{
puts("-1");
}
else
{
printf("%lld\n",ans);
}
return ;
}
/*
3 4
7 2
0 4
2 6
1 2 40
1 2 70
1 2 90
1 2 120
*/

最新文章

  1. Linux indent
  2. Ubuntu的多文件编译以及c语言的数组、函数
  3. vbs 的二个解释程序区别与切换及与BAT互调用。
  4. tomcat6类加载器与类加载顺序
  5. pitch yaw roll 的区别
  6. UOJ #149 [NOIP 2015] 子串
  7. 【原】jquery图片预览
  8. 优先队列 UVA 11997 K Smallest Sums
  9. 【转】你真的理解Python中MRO算法吗?
  10. php 魔鬼训练
  11. struts2 I18N 国际化
  12. Core Java Volume I — 4.7. Packages
  13. 壮美大山包-2017中国大山包国际超百公里ITRA积分赛赛记
  14. linux下crontab定时执行shell脚本调用oracle 存储过程
  15. GC调优在Spark应用中的实践(转载)
  16. Mysql thread 与 OS thread
  17. 如何创建线程第一种继承Thread类
  18. Tkinter添加图片
  19. 在SpringMVC中使用@RequestBody注解处理json时,报出HTTP Status 415的解决方案
  20. Round() 四舍五入 js银行家算法

热门文章

  1. tmp_获取下一个回文数
  2. __vet_atags
  3. Nastya Studies Informatics CodeForces - 992B (大整数)
  4. UIAutomator输入中文
  5. 树状数组 - BZOJ 1103 [POI2007]大都市
  6. 程序员必需知道的windows快捷键
  7. python - 接口自动化测试实战 - case1 - 优化版
  8. FastText 介绍
  9. linux下编译静态库openssl
  10. BZOJ2527 [Poi2011]Meteors 【整体二分 + 树状数组】