hdu4292网络流dinic
因为数组开小了,导致tle了一整天:(
tle的几点原因:http://blog.csdn.net/ameir_yang/article/details/53698478
思路都是对的,把每个人进行拆点,和dining那题差不多,加一个超级源一个超级汇
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cassert> #include<iomanip> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const double g=10.0,eps=1e-9; const int N=850+10,maxn=201000,inf=9999999; struct Node { int to,next,cap; }e[maxn]; int s,t,cnt,dis[N]; int head[N]; void add(int u,int v,int c) { e[cnt].to=v; e[cnt].cap=c; e[cnt].next=head[u]; head[u]=cnt++; e[cnt].to=u; e[cnt].cap=0; e[cnt].next=head[v]; head[v]=cnt++; } bool bfs() { memset(dis,-1,sizeof dis); dis[s]=0; queue<int>q; q.push(s); while(!q.empty()){ int x=q.front(); q.pop(); for(int i=head[x];i!=-1;i=e[i].next) { int temp=e[i].to; if(dis[temp]==-1&&e[i].cap>0) { dis[temp]=dis[x]+1; q.push(temp); } } } return dis[t]!=-1; } int dfs(int x,int mx)//a是找到的增广路上最小的流量 { if(x==t)return mx; int flow=0; for(int i=head[x];i!=-1;i=e[i].next) { int temp=e[i].to,f; if(dis[temp]==dis[x]+1&&e[i].cap>0&&(f=dfs(temp,min(mx,e[i].cap)))) { e[i].cap-=f; e[i^1].cap+=f; return f; } } dis[x]=-2; return 0; } int max_flow() { int ans=0,f; while(bfs()){ while((f=dfs(s,inf)))ans+=f; } return ans; } int main() { /* ios::sync_with_stdio(false); cin.tie(0);*/ int n,f,d,a; char op; while(~scanf("%d%d%d",&n,&f,&d)){ cnt=0; memset(head,-1,sizeof head); s=0,t=f+d+2*n+1; for(int i=1;i<=f;i++) { scanf("%d",&a); add(0,i,a); } for(int i=1;i<=d;i++) { scanf("%d",&a); add(f+2*n+i,f+2*n+d+1,a); } for(int i=1;i<=n;i++) { getchar(); for(int j=1;j<=f;j++) { scanf("%c",&op); if(op=='Y')add(j,f+i,1); } } for(int i=1;i<=n;i++) { getchar(); add(f+i,f+i+n,1); for(int j=1;j<=d;j++) { scanf("%c",&op); if(op=='Y')add(f+n+i,f+2*n+j,1); } } int ans=max_flow(); printf("%d\n",ans); } return 0; }
顺便把dining的dinic写法加上来
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cassert> #include<iomanip> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const double g=10.0,eps=1e-9; const int N=400+10,maxn=16,inf=9999999; struct Node { int to,next,cap; }e[N*10]; int s,t,cnt,dis[N<<2]; int head[N<<2]; void add(int u,int v,int c) { e[cnt].to=v; e[cnt].cap=c; e[cnt].next=head[u]; head[u]=cnt++; e[cnt].to=u; e[cnt].cap=0; e[cnt].next=head[v]; head[v]=cnt++; } bool bfs() { memset(dis,-1,sizeof dis); dis[s]=0; queue<int>q; q.push(s); while(!q.empty()){ int x=q.front(); q.pop(); for(int i=head[x];i!=-1;i=e[i].next) { int temp=e[i].to; if(dis[temp]==-1&&e[i].cap>0) { dis[temp]=dis[x]+1; q.push(temp); } } } return dis[t]!=-1; } int dfs(int x,int mx)//a是找到的增广路上最小的流量 { if(x==t)return mx; int flow=0; for(int i=head[x];i!=-1;i=e[i].next) { int temp=e[i].to,f; if(dis[temp]==dis[x]+1&&e[i].cap>0&&(f=dfs(temp,min(mx-flow,e[i].cap)))) { e[i].cap-=f; e[i^1].cap+=f; flow+=f; } } if(!flow)dis[x]=-2; return flow; } int max_flow() { int ans=0,f; while(bfs()){ while((f=dfs(s,inf)))ans+=f; } return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0); int n,f,d; while(cin>>n>>f>>d){ cnt=0; memset(head,-1,sizeof head); for(int i=1;i<=f;i++)add(0,i,1); for(int i=1;i<=d;i++)add(f+2*n+i,f+2*n+d+1,1); for(int i=1;i<=n;i++) { int a,b,k; cin>>a>>b; while(a--){ cin>>k; add(k,f+i,1); } while(b--){ cin>>k; add(f+n+i,f+2*n+k,1); } } for(int i=1;i<=n;i++)add(f+i,f+i+n,1); s=0,t=f+d+2*n+1; int ans=max_flow(); cout<<ans<<endl; } return 0; }