水题= =
先求一遍最短路,求出d数组,对于一条边(u,v) 若d[u]+边权==d[v] 则他是最短路中的边,找出所有这样的遍,然后限制点的流量(拆点),跑最大流即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdlib> 6 #include<cmath> 7 #include<vector> 8 9 using namespace std; 10 11 #define dout printf 12 13 typedef long long ll; 14 const int Maxn=1010; 15 const ll INF=4557430888798830399ll; 16 int n,m,N; 17 ll g[Maxn][Maxn]; 18 ll d[Maxn*2]; 19 bool flag[Maxn]; 20 21 struct Edge{ 22 int to; 23 ll cap,flow; 24 int next; 25 Edge(int to=0,ll cap=0,int next=0):to(to),cap(cap),next(next){ 26 flow=0; 27 } 28 ll adv(){ 29 return cap-flow; 30 } 31 }edges[2000010];int tot=1,fir[Maxn*2]; 32 33 void AddEdge(int from,int to,ll cap){ 34 edges[++tot]=Edge(to,cap,fir[from]);fir[from]=tot; 35 edges[++tot]=Edge(from,0,fir[to]);fir[to]=tot; 36 } 37 38 void init(){ 39 scanf("%d%d",&n,&m);N=2*n; 40 memset(g,0x3f,sizeof g); 41 for(int u,v,w,i=1;i<=m;i++){ 42 scanf("%d%d%d",&u,&v,&w); 43 if(g[u][v]>w) g[u][v]=g[v][u]=w; 44 } 45 46 for(int c,i=1;i<=n;i++){ 47 scanf("%d",&c); 48 AddEdge(i,i+n,(i==1||i==n)?INF:c); 49 } 50 } 51 52 void Dijkstra(){ 53 memset(d,0x3f,sizeof d); 54 memset(flag,0,sizeof flag); 55 d[1]=0; 56 ll MN; 57 int u; 58 for(int T=n;T--;){ 59 MN=INF; 60 for(int i=1;i<=n;i++) if(!flag[i] && d[i]<MN) { 61 MN=d[i]; u=i; 62 } 63 flag[u]=1; 64 for(int i=1;i<=n;i++){ 65 d[i]=min(d[i],d[u]+g[u][i]); 66 } 67 } 68 } 69 70 int q[Maxn],ql,qr; 71 void build(){ 72 q[qr=(ql=0)+1]=n; 73 memset(flag,0,sizeof flag); 74 for(;ql<qr;){ 75 int u=q[++ql]; 76 for(int v=1;v<=n;v++)if(u!=v && d[v]+g[u][v]==d[u]){ 77 AddEdge(v+n,u,INF); 78 if(!flag[v]) q[++qr]=v,flag[v]=1; 79 } 80 } 81 } 82 83 // network-flows begin---------------------------------------------- 84 int s,t; 85 int p[Maxn*2],cur[Maxn*2],num[Maxn*2]; 86 #define e edges[i] 87 88 inline ll Augment(){ 89 ll a=INF; 90 for(int x=t;x!=s;x=edges[p[x]^1].to){ 91 a=min(a,edges[p[x]].adv()); 92 } 93 for(int x=t;x!=s;x=edges[p[x]^1].to){ 94 edges[p[x]].flow+=a; 95 edges[p[x]^1].flow-=a; 96 } 97 return a; 98 } 99 inline void BFS(int start,bool flag){ 100 for(int i=1;i<=N;i++)d[i]=N; 101 d[q[qr=(ql=0)+1]=start]=0; 102 for(int x;ql<qr;){ 103 x=q[++ql]; 104 for(int i=fir[x];i;i=e.next){ 105 if((flag^(bool)e.adv())&&d[e.to]==N){ 106 d[q[++qr]=e.to]=d[x]+1; 107 } 108 } 109 } 110 } 111 inline ll ISAP(){ 112 s=1,t=N; 113 BFS(t,1); 114 ll flow=0; 115 memcpy(cur,fir,sizeof cur); 116 for(int i=1;i<=N;i++)num[d[i]]++; 117 for(int i=1;i<=d[s];i++)if(!num[i])return 0; 118 for(int x=s;d[s]<N;){ 119 if(x==t){ 120 flow+=Augment(); 121 x=s; 122 } 123 int ok=0; 124 for(int&i=cur[x];i;i=e.next){ 125 if(e.adv()&&d[x]==d[e.to]+1){ 126 p[x=e.to]=i; 127 ok=1; 128 break; 129 } 130 } 131 if(!ok){ 132 int M=N; 133 for(int i=fir[x];i;i=e.next){ 134 if(e.adv())M=min(M,(int)d[e.to]+1); 135 } 136 if(!--num[d[x]])break; 137 num[d[x]=M]++; 138 cur[x]=fir[x]; 139 if(x!=s)x=edges[p[x]^1].to; 140 } 141 } 142 return flow; 143 } 144 //network-flows end----------------------------------------------------------- 145 146 int main(){ 147 freopen("network.in","r",stdin); 148 freopen("network.out","w",stdout); 149 init(); 150 Dijkstra(); 151 build(); 152 cout<<ISAP(); 153 return 0; 154 }
时间: 2024-10-24 17:18:41