1.思路
首先是想了半天硬是没想出来,看了这个解题报告才知道建的图
然后是敲代码又范了很多错误,果然是逻辑思维不严密,基本功不扎实啊!加//的地方都是范过错误的地方,调了我整整一天啊!
用时还挺多的,没办法,二分求值,顺便用来比较一下各种算法的效率!
预流推进的居然TLE!,看样子代码还是写得不够好,不过有点好的是,移植性好,只要图建好后直接上模板!
2.代码(dinic)
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
#define N 420//双倍
#define M 500000//双倍
#define INF 100000000
#define MAX 1000000000000
struct Node{
int u,v,next;
int c;
};
struct Graph
{
Node E[M];
int first[N];
int _V,_E,src,dest;
int d[N];
int num[N];
int que[N],front,rear;
int flow[N],cap[N];
__int64 map[N][N];
__int64 cost[N*N];
void init(int n){
_V=n,_E=0;
src=0;dest=_V-1;
memset(first,-1,4*_V);
}
void add(int u,int v,int c){
E[_E].u=u,E[_E].v=v,E[_E].c=c,E[_E].next=first[u],first[u]=_E,_E++;
E[_E].u=v,E[_E].v=u,E[_E].c=0,E[_E].next=first[v],first[v]=_E,_E++;
}
bool bfs()
{
memset(d,-1,4*_V);
d[src]=0;
front=rear=0;
que[rear++]=src;
while(front!=rear){
int u=que[front++];
for(int e=first[u];e!=-1;e=E[e].next){
int v=E[e].v;
if(d[v]==-1&&E[e].c){
d[v]=d[u]+1;
que[rear++]=v;
}
if(d[dest]!=-1)return true;
}
}
return false;
}
int dfs(int u,int cap)
{
if(u==dest)return cap;
int rest=cap,aug;
for(int e=first[u];e!=-1&&rest;e=E[e].next){
int v=E[e].v,c=E[e].c;
if(d[v]==d[u]+1&&c){
aug=dfs(v,rest>c?c:rest);
rest-=aug;
E[e].c-=aug;
E[e^1].c+=aug;
}
}
return cap-rest;
}
int dinic(){
int flow=0;
while(bfs())flow+=dfs(src,INF);
return flow;
}
void display(){
for(int i=0; i<_V; i++){
for(int e=first[i]; e!=-1; e=E[e].next){
int u=E[e].u,v=E[e].v;
int c=E[e].c;
cout<<u<<' '<<v<<' ';
printf("%d\n",c);
}
}
}
void build(int n,__int64 limit)
{
init(2*n+2);
int i,j;
for(i=1;i<=n;i++)
{
if(flow[i])
{
add(i,i+n,INF);
add(src,i,flow[i]);
}
if(cap)add(i+n,dest,cap[i]);
}
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
if(map[i][j]<=limit)
add(i,j+n,INF),add(j,i+n,INF);//
}
__int64 solve(int n,int m)
{
int tot=0,tot2=0;
int i,j,k;
for(i=1;i<=n;i++)
{
scanf("%d%d",flow+i,cap+i);
tot+=flow[i];
tot2+=cap[i];
}
for(i=1;i<=n;i++)
{
fill(map[i],map[i]+1+n,MAX);
map[i][i]=0;
}
int u,v,c;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&c);
if(c<map[u][v])map[u][v]=map[v][u]=c;
}
if(tot>tot2)return -1;
for(k=1;k<=n;k++)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i==j)continue;
__int64 t=map[i][k]+map[k][j];
if(t<map[i][j])map[i][j]=t;
}
}
}
int cnt;
cost[cnt=1]=0;//
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
if(map[i][j]<MAX)cost[cnt++]=map[i][j];//
}
sort(cost+1,cost+cnt);
for(i=1,j=1;i<cnt;i++){
if(cost[i]==cost[j-1])continue;
cost[j++]=cost[i];
}
int l=0,r=j-1,mid;
while(l<=r)
{
mid=(l+r)>>1;
build(n,cost[mid]);
if(dinic()==tot)
{
r=mid;//
if(l==r)return cost[r];
}
else l=mid+1;
}
return -1;//
}
}net;
int main()
{
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int n,m;
while(cin>>n>>m)printf("%I64d\n",net.solve(n,m));//
return 0;
}
2.sap
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
#define N 420//双倍
#define M 500000//双倍
#define INF 100000000
#define MAX 1000000000000
struct Node{
int u,v,next;
int c;
};
struct Graph
{
Node E[M];
int first[N];
int _V,_E,src,dest;
int d[N];
int num[N];
int pre[N],cur,next;
int flow[N],cap[N];
__int64 map[N][N];
__int64 cost[N*N];
void init(int n){
_V=n,_E=0;
src=0;dest=_V-1;
memset(first,-1,4*_V);
}
void add(int u,int v,int c){
E[_E].u=u,E[_E].v=v,E[_E].c=c,E[_E].next=first[u],first[u]=_E,_E++;
E[_E].u=v,E[_E].v=u,E[_E].c=0,E[_E].next=first[v],first[v]=_E,_E++;
}
inline bool advance(){
for(int e=first[cur];e!=-1;e=E[e].next){
if(d[cur]==d[E[e].v]+1&&E[e].c){
pre[cur=E[e].v]=e;
return true;
}
}
return false;
}
inline int relable(){
int mini=_V-1;
for(int e=first[cur];e!=-1;e=E[e].next)if(E[e].c&&d[E[e].v]<mini)mini=d[E[e].v];
return mini+1;
}
int sap(){
memset(d,-1,4*_V);//!!!
memset(num,0,4*_V);//
pre[src]=-1;//!!!
int flow=0,aug;
while(d[src]!=_V){
cur=src;
while(cur!=dest){
if(advance())continue;
int lable=relable();
num[d[cur]]--;num[d[cur]=lable]++;
if( !num[d[cur]] || d[src]==_V )return flow;
if(cur!=src)cur=E[pre[cur]].u;//满足可行弧定义
}
aug=INF;
int e=pre[dest],aug=INF;
while(e!=-1)aug=aug<E[e].c?aug:E[e].c,e=pre[E[e].u];
flow+=aug;e=pre[dest];
while(e!=-1)E[e].c-=aug,E[e^1].c+=aug,e=pre[E[e].u];
}
return flow;
}
void build(int n,__int64 limit)
{
init(2*n+2);
int i,j;
for(i=1;i<=n;i++)
{
if(flow[i])
{
add(i,i+n,INF);
add(src,i,flow[i]);
}
if(cap)add(i+n,dest,cap[i]);
}
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
if(map[i][j]<=limit)
add(i,j+n,INF),add(j,i+n,INF);//
}
__int64 solve(int n,int m)
{
int tot=0,tot2=0;
int i,j,k;
for(i=1;i<=n;i++)
{
scanf("%d%d",flow+i,cap+i);
tot+=flow[i];
tot2+=cap[i];
}
for(i=1;i<=n;i++)
{
fill(map[i],map[i]+1+n,MAX);
map[i][i]=0;
}
int u,v,c;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&c);
if(c<map[u][v])map[u][v]=map[v][u]=c;
}
if(tot>tot2)return -1;
for(k=1;k<=n;k++)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i==j)continue;
__int64 t=map[i][k]+map[k][j];
if(t<map[i][j])map[i][j]=t;
}
}
}
int cnt;
cost[cnt=1]=0;//
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
if(map[i][j]<MAX)cost[cnt++]=map[i][j];//
}
sort(cost+1,cost+cnt);
for(i=1,j=1;i<cnt;i++){
if(cost[i]==cost[j-1])continue;
cost[j++]=cost[i];
}
int l=0,r=j-1,mid;
while(l<=r)
{
mid=(l+r)>>1;
build(n,cost[mid]);
if(sap()==tot)
{
r=mid;//
if(l==r)return cost[r];
}
else l=mid+1;
}
return -1;//
}
}net;
int main()
{
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int n,m;
while(cin>>n>>m)printf("%I64d\n",net.solve(n,m));//
return 0;
}
是代码写厥了?
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
#define N 420//双倍
#define M 500000//双倍
#define INF 100000000
#define MAX 1000000000000
int d[N];
struct cmp{
bool operator()(const int &u,const int &v)const{
return d[u]<d[v];
}
};
struct Node{
int u,v,next;
int c;
};
struct Graph
{
Node E[M];
int first[N];
int _V,_E,src,dest;
__int64 rest[N];
int in[N];
priority_queue<int,vector<int>,cmp> active;
int flow[N],cap[N];
__int64 map[N][N];
__int64 cost[N*N];
void init(int n){
_V=n,_E=0;
src=0;dest=_V-1;
memset(first,-1,4*_V);
}
void add(int u,int v,int c){
E[_E].u=u,E[_E].v=v,E[_E].c=c,E[_E].next=first[u],first[u]=_E,_E++;
E[_E].u=v,E[_E].v=u,E[_E].c=0,E[_E].next=first[v],first[v]=_E,_E++;
}
void calHeight(){
memset(d,-1,sizeof(d));
d[dest]=0;
int que[N],front,rear;
front=rear=0;
que[rear++]=dest;
while(front!=rear){
int v=que[front++],u;
for(int e=first[v]; e!=-1; e=E[e].next){
u=E[e].v;
if(d[u]==-1){
d[u]=d[v]+1;
que[rear++]=u;
}
}
}
}
void preprocess(){
for(int i=0;i<_V;i++)rest[i]=in[i]=0;
rest[src]=INF;active.push(src);
}
inline void push(int u){
for(int e=first[u]; e!=-1&&rest[u]; e=E[e].next){
int v=E[e].v,c=E[e].c;
if(d[E[e].v]+1==d[u]&&E[e].c){
int aug=rest[u]<c?rest[u]:c;//!!
rest[v]+=aug,rest[u]-=aug,E[e].c-=aug,E[e^1].c+=aug;
if(!in[v]&&v!=dest&&v!=src){
active.push(v);
in[v]=true;
}
}
}
}
inline bool relable(int u){
d[u]=_V-1;
for(int e=first[u]; e!=-1; e=E[e].next)if(E[e].c&&d[u]>d[E[e].v])d[u]=d[E[e].v];
d[u]++;
return d[u]!=_V;
}
__int64 preFlowPush(){
calHeight();
preprocess();
while(!active.empty()){//!!不记录s,t
int u=active.top();
push(u);//从点u进行推流
if(rest[u]&&relable(u))continue;//可以继续推流
active.pop();in[u]=false;//否则弹出队列
}
return rest[dest];
}
void display(){
for(int i=0; i<_V; i++){
for(int e=first[i]; e!=-1; e=E[e].next){
int u=E[e].u,v=E[e].v,c=E[e].c;
cout<<u<<' '<<v<<' '<<c<<endl;
}
}
}
void build(int n,__int64 limit)
{
init(2*n+2);
int i,j;
for(i=1;i<=n;i++)
{
if(flow[i])
{
add(i,i+n,INF);
add(src,i,flow[i]);
}
if(cap)add(i+n,dest,cap[i]);
}
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
if(map[i][j]<=limit)
add(i,j+n,INF),add(j,i+n,INF);//
}
__int64 solve(int n,int m)
{
int tot=0,tot2=0;
int i,j,k;
for(i=1;i<=n;i++)
{
scanf("%d%d",flow+i,cap+i);
tot+=flow[i];
tot2+=cap[i];
}
for(i=1;i<=n;i++)
{
fill(map[i],map[i]+1+n,MAX);
map[i][i]=0;
}
int u,v,c;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&c);
if(c<map[u][v])map[u][v]=map[v][u]=c;
}
if(tot>tot2)return -1;
for(k=1;k<=n;k++)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i==j)continue;
__int64 t=map[i][k]+map[k][j];
if(t<map[i][j])map[i][j]=t;
}
}
}
int cnt;
cost[cnt=1]=0;//
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
if(map[i][j]<MAX)cost[cnt++]=map[i][j];//
}
sort(cost+1,cost+cnt);
for(i=1,j=1;i<cnt;i++){
if(cost[i]==cost[j-1])continue;
cost[j++]=cost[i];
}
int l=0,r=j-1,mid;
while(l<=r)
{
mid=(l+r)>>1;
build(n,cost[mid]);
if(preFlowPush()==tot)
{
r=mid;//
if(l==r)return cost[r];
}
else l=mid+1;
}
return -1;//
}
}net;
int main()
{
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int n,m;
while(cin>>n>>m)printf("%I64d\n",net.solve(n,m));//
return 0;
}