hdu4292网络流dinic

因为数组开小了,导致tle了一整天:(

tle的几点原因:http://blog.csdn.net/ameir_yang/article/details/53698478

思路都是对的,把每个人进行拆点,和dining那题差不多,加一个超级源一个超级汇

#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;
}
View Code

顺便把dining的dinic写法加上来

#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;
}
View Code

 

posted @ 2017-05-26 13:04  walfy  阅读(152)  评论(0编辑  收藏  举报