2018 Benelux Algorithm Programming Contest (BAPC 18)I In Case of an Invasion, Please. . .
阿新 • • 發佈:2019-01-03
題意:一副無向有權圖,每個點有一些人,某些點是避難所(有容量),所有人要去避難所,問最小時間所有人都到達避難所,
題解:dij+二分+最大流check,注意到避難所最多10個,先挨個dij求到避難所的時間,然後二分時間,在這個時間之內的建邊,s向避難所建邊,流量是避難所容量,可達的避難所向點建邊,流量inf,點向t建邊,流量為人的個數,看能不能滿流即可,wa點:maxflow裡的inf忘改,maxn開小了= =
//#pragma GCC optimize(2) //#pragma GCC optimize(3) //#pragma GCC optimize(4) //#pragma GCC optimize("unroll-loops") //#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #include<bits/stdc++.h> #define fi first #define se second #define db double #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define vi vector<int> #define mod 998244353 #define ld long double //#define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pll pair<ll,ll> #define pil pair<int,ll> #define pli pair<ll,int> #define pii pair<int,int> #define ull unsigned long long //#define base 1000000000000000000 #define fin freopen("a.txt","r",stdin) #define fout freopen("a.txt","w",stdout) #define fio ios::sync_with_stdio(false);cin.tie(0) inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;} inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;} template<typename T>inline T const& MAX(T const &a,T const &b){return a>b?a:b;} template<typename T>inline T const& MIN(T const &a,T const &b){return a<b?a:b;} inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;} inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;} using namespace std; const ull ba=233; const db eps=1e-9; const ll INF=0x3f3f3f3f3f3f3f3f; const int N=100000+100,maxn=4000000+10,inf=0x3f3f3f3f; vector<pil>v[N]; ll d[12][N],a[N],b[20]; priority_queue<pli,vector<pli>,greater<pli>>q; void dij(int s,int id) { memset(d[id],INF,sizeof d[id]); d[id][s]=0; q.push(mp(d[id][s],s)); while(!q.empty()) { pli u=q.top();q.pop(); if(u.fi>d[id][u.se])continue; for(pil x:v[u.se]) { if(d[id][u.se]+x.se<d[id][x.fi]) { d[id][x.fi]=d[id][u.se]+x.se; q.push(mp(d[id][x.fi],x.fi)); } } } } struct edge{ int to,Next; ll c; }e[maxn]; int s,t,cnt,head[N],cur[N]; void init(){cnt=0;memset(head,-1,sizeof head);} void add(int u,int v,ll c) { e[cnt].to=v;e[cnt].c=c;e[cnt].Next=head[u];head[u]=cnt++; e[cnt].to=u;e[cnt].c=0;e[cnt].Next=head[v];head[v]=cnt++; } int dis[N]; bool bfs() { queue<int>q; memset(dis,-1,sizeof dis); dis[s]=1;q.push(s); while(!q.empty()) { int x=q.front();q.pop(); for(int i=head[x];~i;i=e[i].Next) { int y=e[i].to; if(dis[y]==-1&&e[i].c>0) { dis[y]=dis[x]+1; q.push(y); } } } return dis[t]!=-1; } ll dfs(int u,ll mx) { if(u==t)return mx; ll flow=0,f; for(int &i=cur[u];~i;i=e[i].Next) { int x=e[i].to; if(dis[x]==dis[u]+1&&e[i].c>0&&(f=dfs(x,min(mx-flow,1ll*e[i].c)))) { e[i].c-=f; e[i^1].c+=f; flow+=f; if(flow==mx)break; } } if(flow==0)dis[u]=-2; return flow; } ll maxflow() { ll ans=0,f; while(bfs()) { for(int i=0;i<=t;i++)cur[i]=head[i]; while((f=dfs(s,INF)))ans+=f; } return ans; } int n,m,c; bool ok(ll x) { init();s=n+c+1,t=n+c+2; ll sum=0; for(int i=1;i<=c;i++) { add(s,i,b[i]); for(int j=1;j<=n;j++)if(d[i][j]<=x)add(i,c+j,INF); } for(int i=1;i<=n;i++)add(c+i,t,a[i]),sum+=a[i]; return maxflow()==sum; } int main() { scanf("%d%d%d",&n,&m,&c); for(int i=1;i<=n;i++)scanf("%lld",&a[i]); for(int i=1;i<=m;i++) { int a,b;ll c;scanf("%d%d%lld",&a,&b,&c); v[a].pb(mp(b,c));v[b].pb(mp(a,c)); } vector<ll>te; for(int i=1,x;i<=c;i++) { scanf("%d%lld",&x,&b[i]),dij(x,i); for(int j=1;j<=n;j++)te.pb(d[i][j]); } sort(te.begin(),te.end());te.erase(unique(te.begin(),te.end()),te.end()); int l=-1,r=te.size(); while(l<r-1) { int mid=(l+r)>>1; if(ok(te[mid]))r=mid; else l=mid; } printf("%lld\n",te[r]); return 0; } /******************** ********************/