本来是个水题
然后我从早晨5点半开始一共用了4个半小时。。。。
先说题吧。。。
首先把这个图的最短路图求出来
what is 最短路图?
就是由许多最短路构成的图啊。。。也就是省去了一些没用的边,怎么判断呢?
具体方法就是首先跑一次spfa
然后就求了出来单源的最短路了,然后求最短路图:如果对于一条边,一个端点到1的距离+这个边的边权==另一个端点到1的距离
那么就加入最短路图
然后一次最小割就可以了
然后大家可以“欣赏”一下我是如何颓废了3个小时的。。。。
我bfs的时候最一开始没有把1的访问标志设置成TRUE。。。。。
真是弱爆了。。。。
#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
#define MAX 250000
#define maxn 600
#define pb push_back
#define inf 0x7fffffff/3
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
int n;
struct dinic
{
int to[2*MAX],flow[2*MAX],next[2*MAX],head[MAX];
int num;
dinic()
{
num=1;
}
void add_edge(int From,int To,int Cap)
{
num++;
to[num]=To;
flow[num]=Cap;
next[num]=head[From];
head[From]=num;
num++;
to[num]=From;
flow[num]=0;
next[num]=head[To];
head[To]=num;
}
int s,t,done[maxn],cur[maxn],d[maxn];
bool bfs()
{
memset(d,0,sizeof(d));
memset(done,0,sizeof(done));
queue<int>q;
q.push(s);
d[s]=1;
done[s]=1;//!!!!!!!!!!!!!!!!!!!!!!
while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=head[now];i;i=next[i])
{
if(!done[to[i]]&&flow[i])
{
d[to[i]]=d[now]+1;
q.push(to[i]);
done[to[i]]=1;
}
}
}
return done[t];
}
int dfs(int x,int a)
{
if(t==x||!a)
return a;
int Flow=0;
for(int w=head[x],f;w;w=next[w])
{
if(d[to[w]]==d[x]+1&&(f=dfs(to[w],min(a,flow[w])))>0)
{
Flow+=f;
flow[w]-=f;
flow[w^1]+=f;
a-=f;
if(!a)
break;
}
}
return Flow;
}
int maxflow(int S,int T)
{
this->s=S;
this->t=T;
int answer=0;
while(bfs())
{
answer+=dfs(s,inf);
}
return answer;
}
}wbysr;
int to[2*MAX],from[2*MAX],cost[2*MAX],value[2*MAX],dis[maxn],done[maxn],head[MAX*2],next[2*MAX];
int m,tot=0;
void add(int from,int To,int Cost,int Value)
{
to[++tot]=To;
cost[tot]=Cost;
value[tot]=Value;
next[tot]=head[from];
head[from]=tot;
}
inline void spfa()
{
queue<int>q;
memset(dis,0x3f,sizeof(dis));
// memset(done,0,sizeof(done));
dis[1]=0;
done[1]=1;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
q.push(1);
while(!q.empty())
{
int now=q.front();
q.pop();
done[now]=0;
for(int i=head[now];i;i=next[i])
if(dis[to[i]]>dis[now]+cost[i])
{
dis[to[i]]=dis[now]+cost[i];
if(!done[to[i]])
done[to[i]]=1,q.push(to[i]);
}
}
return;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1,a1,a2,a3,a4;i<=m;i++)
scanf("%d%d%d%d",&a1,&a2,&a3,&a4),add(a1,a2,a3,a4),add(a2,a1,a3,a4);
spfa();
printf("%d\n",dis[n]);
//make
queue<int>q;
q.push(n);
memset(done,0,sizeof(done));
done[n]=1;
while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=head[now];i;i=next[i])
if(dis[to[i]]+cost[i]==dis[now])
{
wbysr.add_edge(to[i],now,value[i]);
if(!done[to[i]])
done[to[i]]=1,q.push(to[i]);
}
}
printf("%d\n",wbysr.maxflow(1,n));
return 0;
}