Tyvj P2207 上学路线route

P2207 上学路线route

正反两遍spfa,判断某条边是否是在最短路上,如果是的话就建边,跑最大流

  1 #include<cstdio>
  2 #include<queue>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 #define maxn 250000
  7 #define inf 0x3f3f3f3f
  8 int n,m,src,dec,ans,cur[maxn],d[maxn],ansx,y,z,num,front2[maxn*2];
  9 int lev[maxn],front[maxn*2],head,tail,que[maxn*2],tot=1,dis[maxn],dis1[maxn];
 10 bool vis[maxn];
 11 struct node{
 12     int to,next,cap;
 13 }e[maxn*2];
 14
 15 struct Edge{
 16     int u,v,next,w,d;
 17 }edge[maxn*2],edge2[maxn*2];
 18
 19 inline void add(int u,int v,int w)
 20 {
 21     e[++tot].to=v; e[tot].next=front[u]; e[tot].cap=w; front[u]=tot;
 22     e[++tot].to=u; e[tot].next=front[v]; e[tot].cap=0; front[v]=tot;
 23 }
 24
 25 void ins(int u,int v,int w,int d)
 26 {
 27     edge[++num].v=v;
 28     edge[num].w=w;
 29     edge[num].u=u;
 30     edge[num].next=front2[u];
 31     edge[num].d=d;
 32     front2[u]=num;
 33 }
 34
 35 char ch;
 36 inline void read(int &now)
 37 {
 38     ch=getchar(); now=0;
 39     while(ch>‘9‘||ch<‘0‘) ch=getchar();
 40     while(ch>=‘0‘&&ch<=‘9‘) now=now*10+ch-‘0‘,ch=getchar();
 41 }
 42
 43 bool bfs()
 44 {
 45     for(int i=src;i<=dec;i++) lev[i]=-1,cur[i]=front[i];
 46     head=tail=0;
 47     que[tail++]=src; lev[src]=0;
 48     while(head<tail)
 49     {
 50         for(int i=front[que[head]];i;i=e[i].next)
 51             if(e[i].cap>0&&lev[e[i].to]==-1)
 52             {
 53                 lev[e[i].to]=lev[que[head]]+1;
 54                 que[tail++]=e[i].to;
 55                 if(e[i].to==dec) return true;
 56             }
 57         head++;
 58     }
 59     return false;
 60 }
 61
 62 void spfa(int s)
 63 {
 64     queue<int>q;
 65     for(int i=1;i<=n;i++) dis[i]=inf;
 66     memset(vis,false,sizeof(false));
 67     vis[s]=1; dis[s]=0;
 68     q.push(s);
 69     while(!q.empty())
 70     {
 71         int cur=q.front(); q.pop();
 72         for(int i=front2[cur];i;i=edge[i].next)
 73         {
 74             if(dis[edge[i].v]>dis[cur]+edge[i].w)
 75             {
 76                 dis[edge[i].v]=dis[cur]+edge[i].w;
 77                 if(!vis[edge[i].v])
 78                 {
 79                     vis[edge[i].v]=1;
 80                     q.push(edge[i].v);
 81                 }
 82             }
 83         }
 84         vis[cur]=false;
 85     }
 86 }
 87
 88 int dinic(int u,int flow)
 89 {
 90     if(u==dec) return flow;
 91     int res=0,delta;
 92     for(int i=cur[u];i;i=e[i].next)
 93     {
 94         if(e[i].cap>0&&lev[e[i].to]>lev[u])
 95         {
 96             delta=dinic(e[i].to,min(e[i].cap,flow-res));
 97             if(delta)
 98             {
 99                 e[i].cap-=delta; e[i^1].cap+=delta;
100                 res+=delta; if(res==flow) break;
101             }
102         }
103     }
104     if(res!=flow) lev[u]=-1;
105     return res;
106 }
107
108 int main()
109 {
110     read(n); read(m);
111     for(int i=1;i<=m;i++)
112     {
113         int u,v,w,d;
114         read(u); read(v); read(w); read(d);
115         edge2[i].u=u; edge2[i].v=v; edge2[i].w=w; edge2[i].d=d;
116         ins(u,v,w,d);
117         ins(v,u,w,d);
118     }
119     src=1; dec=n;
120     spfa(src);
121     printf("%d\n",dis[n]);
122     for(int i=1;i<=n;i++) dis1[i]=dis[i];
123     spfa(dec);
124     for(int i=1;i<=m;i++)
125     {
126         if(dis1[edge2[i].u]<dis1[edge2[i].v])
127         {
128             if(edge2[i].w+dis1[edge2[i].u]+dis[edge2[i].v]==dis1[n])
129             add(edge2[i].u,edge2[i].v,edge2[i].d);
130         }
131         else{
132             if(edge2[i].w+dis1[edge2[i].v]+dis[edge2[i].u]==dis1[n])
133             add(edge2[i].v,edge2[i].u,edge2[i].d);
134         }
135     }
136     while(bfs())
137     ans+=dinic(src,inf);
138     printf("%d\n",ans);
139     return 0;
140 }

时间: 2024-11-16 05:33:12

Tyvj P2207 上学路线route的相关文章

BZOJ 1266 上学路线route(最小割)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1266 题意:给出一个无向图,每条边有长度和代价.求出1到n的最短路.之后删掉一些边使得1到n的最短路变大?在此情况下使得删掉边的代价之和最小. 思路:首先求出每个点到1和n的最短路.之后可以确定每条边是否为关键边(就是最短路上的边).将关键边建立网络流图,求最小割即可. struct node { int v,cap,next; }; node edges[N]; int head[N

BZOJ1266: [AHOI2006]上学路线route

1266: [AHOI2006]上学路线route Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 1273  Solved: 435[Submit][Status] Description 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的. 可可:“很可能我们在上学的路途上浪费了大量的时间,让我们写一个程序来计算上学需要的最少时间吧

BZOJ 1266: [AHOI2006]上学路线route(最短路+最小割)

第一问最短路.第二问,先把最短路的图建出来(边(u,v)满足d[s->u]+d[v->t]+d(u,v)==最短路径长度,就在图中,可以从源点和汇点分别跑一次最短路得到每个点到源点和汇点的最短路),然后跑一遍最大流就OK了. --------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #

bzoj 1266 1266: [AHOI2006]上学路线route

1266: [AHOI2006]上学路线route Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 2356  Solved: 841[Submit][Status][Discuss] Description 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的. 可可:“很可能我们在上学的路途上浪费了大量的时间,让我们写一个程序来计算上

bzoj 1266 [AHOI2006] 上学路线 route 题解

转载请注明:http://blog.csdn.net/jiangshibiao/article/details/23989499 [原题] 1266: [AHOI2006]上学路线route Time Limit: 3 Sec  Memory Limit: 162 MB Submit: 1084  Solved: 360 [Submit][Status] Description 可可和卡卡家住合肥市的东郊.每天上学他们都要转车多次才干到达市区西端的学校. 直到有一天他们两人參加了学校的信息学奥林

bzoj1266 [AHOI2006]上学路线route floyd+最小割

1266: [AHOI2006]上学路线route Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 2490  Solved: 898[Submit][Status][Discuss] Description 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的. 可可:“很可能我们在上学的路途上浪费了大量的时间,让我们写一个程序来计算上

【bzoj1266】[AHOI2006]上学路线route 最短路+最小割

题目描述 可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的. 可可:“很可能我们在上学的路途上浪费了大量的时间,让我们写一个程序来计算上学需要的最少时间吧!” 合肥市一共设有N个公交车站,不妨将它们编号为1…N的自然数,并认为可可和卡卡家住在1号汽车站附近,而他们学校在N号汽车站.市内有M条直达汽车路线,执行第i条路线的公交车往返于站点pi和qi之间,从起点到终点需要花费的时间为

BZOJ 1266 [AHOI2006]上学路线route

先对原图求一遍最短路..这里用什么算法都行,毕竟N很小直接floyd就可以啦.. 然后把可以当做最短路上的边加入到一个新图当中去..求一遍最小割(最大流)就好啦.. 可以当做最短路的的边的条件:G[1][u]+time+G[v][N]=G[1][N] 然而这题我WA了三次..因为没有在跑完最短路后重新建图,而是直接在Dinic用BFS构造残余网络分层图的时候判断条件G[1][u]+time+G[v][N]=G[1][N]..这会导致有可能无法反向增广..QAQ我毕竟还是too simple需要提

【最短路】【spfa】【最小割】【Dinic】bzoj1266 [AHOI2006]上学路线route

原问题等价于断掉一些边,让原来所有的最短路全都无法联通S和T. 先求最短路,然后把在最短路上的边(dis[u[i]]+w[i]==dis[v[i]])加入新图里,跑最小割.显然. 注意是无向图. #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define INF 2147483647 #define MAXN 511 #