HDU 5855 Less Time, More profit(最大权闭合图)

来源:互联网 发布:poi的软件 编辑:程序博客网 时间:2024/05/16 18:02

nm
tipayi
kkproi
propayLtp


tINFsumsumflow


代码:

#include <map>#include <set>#include <ctime>#include <stack>#include <queue>#include <cmath>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <sstream>#include <cstdlib>#include <iostream>#include <algorithm>#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;#define   MAX           1000005#define   MAXN          1000005#define   maxnode       205#define   sigma_size    26#define   lson          l,m,rt<<1#define   rson          m+1,r,rt<<1|1#define   lrt           rt<<1#define   rrt           rt<<1|1#define   middle        int m=(r+l)>>1#define   LL            long long#define   ull           unsigned long long#define   mem(x,v)      memset(x,v,sizeof(x))#define   lowbit(x)     (x&-x)#define   pii           pair<int,int>#define   bits(a)       __builtin_popcount(a)#define   mk            make_pair#define   limit         10000//const int    prime = 999983;const int    INF   = 0x3f3f3f3f;const LL     INFF  = 0x3f3f;const double pi    = acos(-1.0);const double inf   = 1e18;const double eps   = 1e-4;const LL    mod    = 772002;const ull    mx    = 133333331;/*****************************************************/inline void RI(int &x) {      char c;      while((c=getchar())<'0' || c>'9');      x=c-'0';      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; }/*****************************************************/const int N = 505;const int M = 100005;struct Isap{    int tot;    int d[N],pre[N],cur[N],gap[N];    int head[N];    struct Edge{        int v,next;        int cap,flow;    }edge[M*2];    void init(){        mem(head,-1);        tot=0;    }    void add_edge(int a, int b, int c){        edge[tot]=(Edge){b,head[a],c,0};        head[a]=tot++;    }    void add(int a,int b, int c){        add_edge(a,b,c);        add_edge(b,a,0);    }    void set_d(int t){        queue<int> q;        mem(d,-1);        mem(gap,0);        d[t]=0;        q.push(t);        while(!q.empty()) {            int u=q.front();q.pop();            ++gap[d[u]];            for(int i=head[u];i!=-1;i=edge[i].next) {                int v=edge[i].v;                if(d[v]==-1) {                    d[v]=d[u]+1;                    q.push(v);                }            }        }    }    int sap(int s,int t,int num) {        set_d(t);        int ans=0,u=s;        int flow=INF;        memcpy(cur,head,sizeof(head));        while(d[s]<num){            int &i=cur[u];            for(;i!=-1;i=edge[i].next) {                int v=edge[i].v;                if(edge[i].cap>edge[i].flow&&d[u]==d[v]+1) {                    u=v;                    pre[v]=i;                    flow=min(flow,edge[i].cap-edge[i].flow);                    if(u==t){                        while(u!=s){                            int j=pre[u];                            edge[j].flow+=flow;                            edge[j^1].flow-=flow;                            u=edge[j^1].v;                        }                        ans+=flow;                        flow=INF;                    }                    break;                }            }            if(i==-1) {                if(--gap[d[u]]==0) break;                int dmin=num-1;                cur[u]=head[u];                for(int j=head[u];j!=-1;j=edge[j].next)                    if(edge[j].cap>edge[j].flow)                        dmin=min(dmin,d[edge[j].v]);                d[u]=dmin+1;                ++gap[d[u]];                if(u!=s) u=edge[pre[u]^1].v;            }        }        return ans;    }}Sap;/*调用方式:Sap.init(); //建边前调用Sap.add(u, v, c); //在u->v之间建一条容量为c的边Sap.sap(s, t, n); //s为源点,t为汇点,n为点的数量*/int p1[205],t1[205];int p2[205];vector<int> v[205];int n,m,L;int check(int x){    Sap.init();    int sum=0;    for(int i=1;i<=m;i++){        Sap.add(0,i,p2[i]);        int flag=0;        for(int j=0;j<v[i].size();j++){            if(t1[v[i][j]]>x) flag=1;        }        if(!flag){            for(int j=0;j<v[i].size();j++){                Sap.add(i,m+v[i][j],INF);            }            sum+=p2[i];        }    }    for(int i=1;i<=n;i++){        if(t1[i]<=x) Sap.add(m+i,n+m+1,p1[i]);    }    int ans=Sap.sap(0,n+m+1,n+m+2);    if(sum-ans>=L) return sum-ans;    else return -1;}int main(){    //freopen("froggy.in","r",stdin);    //freopen("froggy.out","w",stdout);    int t,kase=0;    cin>>t;    while(t--){        cin>>n>>m>>L;        kase++;        for(int i=1;i<=n;i++) scanf("%d%d",&p1[i],&t1[i]);        for(int i=1;i<=m;i++){            int k;            scanf("%d%d",&p2[i],&k);            v[i].clear();            while(k--){                int a;                scanf("%d",&a);                v[i].push_back(a);            }        }        int l=0,r=1e9;        int ans=-1;        while(l<=r){            int mid=(l+r)/2;            int cnt=check(mid);            if(cnt!=-1){                ans=cnt;                r=mid-1;            }            else l=mid+1;        }        printf("Case #%d: ",kase);        if(ans==-1) printf("impossible\n");        else printf("%d %d\n",l,ans);    }       return 0;}
0 0
原创粉丝点击