本来是个水题
然后我从早晨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; }
Bzoj1266 Ahoi2006 上学路线,布布扣,bubuko.com
原文:http://blog.csdn.net/wbysr/article/details/22685591