题目链接:
http://codeforces.com/gym/100526
http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11664&courseid=0
题目大意:
总共N个点,现在有P个人,在T时间内要从起点S走到C个医疗站中的任意一个,M条X到Y的有向边,每条边每个单位时间可以通过的人数是pi,走完这条边耗时ti。
人可以停留在任意一个点,求最多能有多少人到达医疗站。
(1<=C<=N<=1000,0<=M<=1000,1<=P,T<=100,1<=pi,ti<=100)
题目思路:
【最大流】
SPFA居然T了。。
将每个点按照时间拆点{X节点j时间的状态为点X(j)},把X到Y的边pi,ti拆成T-ti条边,每条边从X(j)到Y(j+ti)容量为pi,j为时间从0~T-ti,表示在j时间有pi个人可以从X到Y,到达Y的时间为j+ti。
因为人可以停留在节点上所以X(i)到X(i+1)连一条容量P的边。
每个医疗站的最终时间Ci(T)到超级汇T_T连一条容量为P的边(到达医疗站的人就无限停留直到时间为T到超级汇T_T)
超级源S_S到起点S(0)连一条容量为P的边表示初始起点S有P个人。
最终统计到达超级汇的人数即可。跑一遍最大流。
1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<map> 9 #include<memory.h> 10 #include<time.h> 11 #include<stdio.h> 12 #include<stdlib.h> 13 #include<string.h> 14 //#include<stdbool.h> 15 #include<math.h> 16 #define min(a,b) ((a)<(b)?(a):(b)) 17 #define max(a,b) ((a)>(b)?(a):(b)) 18 #define abs(a) ((a)>0?(a):(-(a))) 19 #define lowbit(a) (a&(-a)) 20 #define sqr(a) ((a)*(a)) 21 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 22 #define mem(a,b) memset(a,b,sizeof(a)) 23 #define eps (1e-8) 24 #define J 10 25 #define mod 1000000007 26 #define MAX 0x7f7f7f7f 27 #define PI 3.14159265358979323 28 #define N 1004 29 #define M 104 30 using namespace std; 31 typedef long long LL; 32 int cas,cass; 33 int n,m,lll,ans; 34 int s,p,t,S,T,nn; 35 int c[N]; 36 int last[N*M+M],vd[N*M+M],d[N*M+M]; 37 struct xxx 38 { 39 int next,to,q; 40 }a[N*M*M]; 41 void add(int x,int y,int f) 42 { 43 a[++lll].next=last[x]; 44 a[lll].to=y; 45 a[lll].q=f; 46 last[x]=lll; 47 } 48 int sap(int u,int f) 49 { 50 int i,v,tt,asp=0,mix=nn-1; 51 if(u==T)return f; 52 for(i=last[u];i;i=a[i].next) 53 { 54 v=a[i].to; 55 if(a[i].q>0) 56 { 57 if(d[u]==d[v]+1) 58 { 59 tt=sap(v,min(f-asp,a[i].q)); 60 asp+=tt; 61 a[i].q-=tt; 62 a[i^1].q+=tt; 63 if(asp==f || d[S]==nn) 64 return asp; 65 } 66 mix=min(mix,d[v]); 67 } 68 } 69 if(asp!=0)return asp; 70 if(!--vd[d[u]])d[S]=nn; 71 else vd[d[u]=mix+1]++; 72 return asp; 73 } 74 int main() 75 { 76 #ifndef ONLINE_JUDGE 77 // freopen("1.txt","r",stdin); 78 // freopen("2.txt","w",stdout); 79 #endif 80 int i,j,k; 81 int x,y,f,dd; 82 for(scanf("%d",&cas);cas;cas--) 83 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 84 // while(~scanf("%s",s+1)) 85 // while(~scanf("%d",&n)) 86 { 87 ans=0;lll=1;mem(vd,0);mem(d,0);mem(last,0); 88 scanf("%d%d%d%d%d",&n,&s,&p,&t,&cass); 89 S=n*t+t+1;T=S+1; 90 nn=T;vd[0]=nn-t+1; 91 add(S,t,p); 92 add(t,S,0); 93 add(t,s*t+1,p); 94 add(s*t+1,t,0); 95 for(i=1;i<=n;i++) 96 { 97 for(j=1;j<t;j++) 98 { 99 add(i*t+j,i*t+j+1,p); 100 add(i*t+j+1,i*t+j,0); 101 } 102 } 103 for(i=1;i<=cass;i++) 104 { 105 scanf("%d",&c[i]); 106 add(c[i]*t+t,T,p); 107 add(T,c[i]*t+t,0); 108 } 109 scanf("%d",&m); 110 for(i=1;i<=m;i++) 111 { 112 scanf("%d%d%d%d",&x,&y,&f,&dd); 113 for(j=1;j+dd<=t;j++) 114 { 115 add(x*t+j,y*t+j+dd,f); 116 add(y*t+j+dd,x*t+j,0); 117 } 118 if(x==s) 119 { 120 add(t,y*t+dd,f); 121 add(y*t+dd,t,0); 122 } 123 } 124 while(d[S]<nn) 125 { 126 f=sap(S,MAX); 127 ans+=f; 128 } 129 printf("%d ",ans); 130 } 131 return 0; 132 } 133 /* 134 // 135 136 // 137 */