【BZOJ 1266】 [AHOI2006]上学路线route
【链接】我是链接,点我呀:)
【题意】
在这里输入题意
【题解】
第一问是个最短路。
第二问。
利用第一问floyd算出来的任意两点之间的最短路。
那么枚举每一条边(x,y)
如果w[1][x]+cost[x][y]+w[y][n]==w[1][n]
那么就说明(x->y)这条边是某条最短路上的必经边。
则我们在一张新的网络中加入(x,y,pi)这条边。
然后我们求这个网络的最小割。
那么1到n就没有办法通过最短路到达了,因为每条最短路都被破坏了。
讨论里好像说有重边。
pre[1]=0不能省。不然貌似会往回走。。
【代码】
#include <bits/stdc++.h> #define LL long long #define rep1(i,a,b) for (int i = a;i <= b;i++) #define rep2(i,a,b) for (int i = a;i >= b;i--) #define all(x) x.begin(),x.end() #define pb push_back #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 using namespace std; const double pi = acos(-1); const int dx[4] = {0,0,1,-1}; const int dy[4] = {1,-1,0,0}; const int M = 15e4; const int N = 500; const int INF = 0x3f3f3f3f; struct abc{ int x,y,t,p; }; int n,m,w[N+10][N+10],flow[N+10][N+10]; abc bian[M]; void add_edge(int x,int y,int z){ flow[x][y]+=z; } queue<int> dl; int pre[N+10]; int main(){ #ifdef LOCAL_DEFINE freopen("rush_in.txt", "r", stdin); #endif ios::sync_with_stdio(0),cin.tie(0); memset(w,0x3f3f3f3f,sizeof w); cin >> n >> m; rep1(i,1,n) w[i][i] = 0; rep1(i,1,m) { cin >> bian[i].x >> bian[i].y >> bian[i].t >> bian[i].p; w[bian[i].x][bian[i].y] = min(w[bian[i].x][bian[i].y],bian[i].t); w[bian[i].y][bian[i].x] = min(w[bian[i].y][bian[i].x],bian[i].t); } rep1(k,1,n) rep1(i,1,n) if (i!=k) rep1(j,1,n) if (j!=k && j!= i && w[i][k]+w[k][j]<w[i][j]) w[i][j] = w[i][k]+w[k][j]; rep1(i,1,m){ int x = bian[i].x,y = bian[i].y,v = bian[i].t; if (w[1][x]+w[y][n]+v == w[1][n]){ add_edge(x,y,bian[i].p); } if (w[1][y]+w[x][n]+v == w[1][n]){ add_edge(y,x,bian[i].p); } } cout<<w[1][n]<<endl; int ans = 0; while (1){ memset(pre,255,sizeof pre); while (!dl.empty()) dl.pop(); dl.push(1); pre[1] = 0; while (!dl.empty()){ int x = dl.front();dl.pop(); for (int i = 1;i <= n;i++) if (pre[i]==-1 && x!=i && flow[x][i]>0){ pre[i] = x; dl.push(i); if (i==n) break; } } if (pre[n]==-1) break; int temp = 0x3f3f3f3f; int y = n; while (1){ int x = pre[y]; //cout<<x<<endl; if (x==0) break; temp = min(temp,flow[x][y]); y = x; } y = n; while (1){ int x = pre[y]; if (x==0) break; flow[x][y]-=temp; flow[y][x]+=temp; y = x; } ans+=temp; } cout<<ans<<endl; return 0; }
相关推荐
IT之家 2020-03-11
graseed 2020-10-28
zbkyumlei 2020-10-12
SXIAOYI 2020-09-16
jinhao 2020-09-07
impress 2020-08-26
liuqipao 2020-07-07
淡风wisdon大大 2020-06-06
yoohsummer 2020-06-01
chenjia00 2020-05-29
baike 2020-05-19
扭来不叫牛奶 2020-05-08
hxmilyy 2020-05-11
黎豆子 2020-05-07
xiongweiwei00 2020-04-29
Cypress 2020-04-25
冰蝶 2020-04-20