hdu2883

来源:互联网 发布:java yield 编辑:程序博客网 时间:2024/06/12 13:13
这道题目比前面一道求满流的题目多了一点不一样,我理解就是离散化,因为si,ei的范围实在太大,但n的范围却不大,则

把所有si,ei列出来,排序,得到最多2*n-1个区间,则每个区间就是各节点,到汇点的容量限制就是m*区间长度。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int INF=1<<30;int si[210],ei[210],ni[210],ti[210],head[2100],h[2100],num[4200];int a[410],n,m,sum;int cnt,ans,c;struct edge{       int x,y,flow,nxt,op;}em[1000010];void add(int x,int y,int c){     em[++cnt].x=x;     em[cnt].y=y;     em[cnt].flow=c;     em[cnt].nxt=head[x];     head[x]=cnt;     em[cnt].op=cnt+1;     cnt++;     em[cnt].x=y;     em[cnt].y=x;     em[cnt].flow=0;     em[cnt].nxt=head[y];     head[y]=cnt;     em[cnt].op=cnt-1;}int dfs(int x,int flow){    if(x==n+c)    return flow;    int temp=flow,pos=n+c+1;    for(int j=head[x];j;j=em[j].nxt)    {            int y=em[j].y;            int w=em[j].flow;            if(h[x]==h[y]+1&&w>0)            {                                 int temp_flow=dfs(y,min(temp,w));                                 temp-=temp_flow;                                 em[j].flow-=temp_flow;                                 em[em[j].op].flow+=temp_flow;                                 if(!temp||h[0]==n+c+1)                                 return flow-temp;            }            if(w>0&&h[y]<pos)            pos=h[y];    }    if(temp==flow)    {                  num[h[x]]--;                  if(num[h[x]]==0)                  h[0]=n+c+1;                  else                  {                      h[x]=pos+1;                      num[h[x]]++;                  }    }    return flow-temp;}void isap(){     memset(h,0,sizeof(h));     memset(num,0,sizeof(num));     while(h[0]<n+c+1)     {                    ans+=dfs(0,INF);     } //    printf("%d %d\n",sum,ans);     if(ans==sum)     printf("Yes\n");     else     printf("No\n");}int main(){    while(2==scanf("%d%d",&n,&m))    {                                 sum=0;                                 int tot=0;                                 cnt=0;                                 memset(head,0,sizeof(head));                                 for(int i=1;i<=n;i++)                                 {                                         scanf("%d%d%d%d",si+i,ni+i,ei+i,ti+i);                                                                                  a[++tot]=si[i];                                         a[++tot]=ei[i];                                         add(0,i,ni[i]*ti[i]);                                         sum+=ni[i]*ti[i];                                 }                                 sort(a+1,a+tot+1);                                 c=0;                                 for(int i=1;i<=tot;i++)                                 if(a[c]!=a[i])                                 a[++c]=a[i];                               /*  for(int i=1;i<=c;i++)                                 printf("%d\n",a[i]);*/                                 for(int i=1;i<=c-1;i++)                                 {                                         int num=(a[i+1]-a[i])*m;                                         add(n+i,n+c,num);                                 }                                 for(int i=1;i<=c-1;i++)                                 {                                         for(int j=1;j<=n;j++)                                         if(si[j]<=a[i]&a[i+1]<=ei[j])                                         add(j,i+n,INF);                                 }                                  ans=0;                                 isap();    }        return 0;}


原创粉丝点击