1. 程式人生 > >BZOJ1266: [AHOI2006]上學路線route

BZOJ1266: [AHOI2006]上學路線route

geo targe algorithm 最小割 text name floyd 上學路線 while

【傳送門:BZOJ1266】


簡要題意:

  給出一個有n個點,m條無向邊的圖,每條邊有長度和摧毀的代價,首先求出從1到n的最短路徑,然後要求花費最小代價摧毀一些邊,使得圖中1到n的最短路徑變長,求出最小代價


題解:

  求最短路徑,簡直。。好吧,SPFA或floyd搞定

  求最小代價,我們可以想一下,先把所有最短路徑找出來,然後刪除一些邊,使得所有路徑都有邊被摧毀,有可能有多條路徑覆蓋了同一條邊

  仔細想了想,嗯,用最小代價使所有路徑都有邊,嗯,用最小代價使1到n不連通!!這不是最小割嗎!!

  好的,因為我們要將所有路徑都求出來並建網絡流的圖,所以我們用floyd來求最短路徑(因為這樣比較方便)


參考代碼:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int f[510][510];
int x[210000],y[210000],d[210000],t[210000];
struct node
{
    int x,y,c,next,other;
}a[410000];int len,last[510];
void ins(int x,int y,int c)
{
    
int k1=++len,k2=++len; a[k1].x=x;a[k1].y=y;a[k1].c=c; a[k1].next=last[x];last[x]=k1; a[k2].x=y;a[k2].y=x;a[k2].c=0; a[k2].next=last[y];last[y]=k2; a[k1].other=k2; a[k2].other=k1; } int h[510],list[510]; int st,ed; bool bt_h() { memset(h,0,sizeof(h));h[st]=1; list[
1]=st; int head=1,tail=1; while(head<=tail) { int x=list[head]; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(a[k].c>0&&h[y]==0) { h[y]=h[x]+1; list[++tail]=y; } } head++; } if(h[ed]==0) return false; else return true; } int findflow(int x,int f) { if(x==ed) return f; int s=0,t; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(h[y]==h[x]+1&&a[k].c>0&&f>s) { t=findflow(y,min(a[k].c,f-s)); s+=t; a[k].c-=t; a[a[k].other].c+=t; } } if(s==0) h[x]=0; return s; } int main() { int n,m; scanf("%d%d",&n,&m); len=0;memset(last,0,sizeof(last)); memset(f,63,sizeof(f)); for(int i=1;i<=n;i++) f[i][i]=0; for(int i=1;i<=m;i++) { scanf("%d%d%d%d",&x[i],&y[i],&d[i],&t[i]); f[x[i]][y[i]]=d[i]; f[y[i]][x[i]]=d[i]; } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) if(i!=k) for(int j=1;j<=n;j++) if(j!=i&&j!=k) f[i][j]=min(f[i][j],f[i][k]+f[k][j]); int dd=f[1][n]; st=1;ed=n; for(int i=1;i<=m;i++) { if(f[1][x[i]]+d[i]+f[y[i]][n]==dd) ins(x[i],y[i],t[i]); if(f[x[i]][n]+d[i]+f[1][y[i]]==dd) ins(y[i],x[i],t[i]); } int ans=0; while(bt_h()==true) { ans+=findflow(st,999999999); } printf("%d\n%d\n",f[1][n],ans); return 0; }

BZOJ1266: [AHOI2006]上學路線route