您的位置:首页 > 理论基础 > 计算机网络

hdu 3572 : Task Schedule (网络流)

2017-09-22 15:25 281 查看
题目链接

题意:

有M个机器,N个任务

对第i个任务,需要在[Si,Ei]这段时间内恰有Pi天被process

每天最多有M个机器同时工作

每一天,一个任务若被process,那么它恰占用一个机器。

题解:建图,设一个超级源点S编号为0,超级汇点T编号为1001,编号[1,500]表示任务[1,500],编号[501,100]表示时间[1,500] (为与原题对应,建边时用500作为偏移量)。

每一天最多同时加工M个任务,故每一天向超级汇点连一条容量为M的边 以满足此不等关系。

每个任务最多需要Pi天,那么超级汇点向每个任务连一条容量为Pi的边。

每个任务要在[Si,Ei]中选时间进行process,那么,从任务i向[Si,Ei]中的每一天都分别连一条容量为1的边。

最后,如果跑得的最大流==sigma(Pi),那么就是"Yes"了

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

namespace FastIO
{
const static int MX=1e6;
bool IOerror=0;
char nc()
{
static char buf[MX],*p1=buf+MX,*pend=buf+MX;
if(p1==pend)
{
p1=buf;
pend=buf+fread(buf,1,MX,stdin);
if(pend==p1)
{
IOerror=1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch)
{
return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';
}
inline int read(int& x)
{
char ch;
while(blank(ch=nc()));
if(IOerror) return 0;
for(x=ch-'0'; (ch=nc())>='0'&&ch<='9'; x=x*10+ch-'0'); //printf("%d===\n",x);
return 1;
}
}
using namespace FastIO;

const int N=1005;
const int M=1000006;
const int INF=0x3f3f3f3f;

struct Edge
{
int to,next;
int flow,cap;    //根据情况设定变量类型
Edge(){}
Edge(int _to,int _next,int _cap,int _flow)
{
to=_to,next=_next,cap=_cap,flow=_flow;
}
};
Edge edge[M<<1];
int head
,tot;
int cur
;
int d
;

void init()
{
memset(head,-1,sizeof(head));
tot=0;
}
inline void addedge(int u,int v,int cap)
{
edge[tot]=Edge(v,head[u],cap,0);
head[u]=tot++;
edge[tot]=Edge(u,head[v],0,0);
head[v]=tot++;
}
int bfs(int s,int t)
{
memset(d,-1,sizeof(d));
queue<int> Q;
Q.push(s),d[s]=0;
while(!Q.empty())
{
int u=Q.front();Q.pop();
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(d[v]==-1&&edge[i].cap>edge[i].flow)
{
d[v]=d[u]+1;
if(v==t) return 1;
Q.push(v);
}
}
}
return ~d[t];
}
int dfs(int s,int t,int a)
{
if(s==t||a==0) return a;
int flow=0,df;
//    for(int& i=cur[s];~i;i=edge[i].next)
for(int i=head[s];~i;i=edge[i].next)
{
int v=edge[i].to;
//        if(d[v]==d[s]+1 &&
//            (df=dfs(v,t,min(a,edge[i].cap-edge[i].flow))>0))    //这种写法 hdu6214 TLE
if(d[v]==d[s]+1&&edge[i].cap>edge[i].flow
&&(df=dfs(v,t,min(a,edge[i].cap-edge[i].flow)))>0)
{
edge[i].flow+=df;
edge[i^1].flow-=df;
flow+=df;
a-=df;
if(a==0) break;
}
}
if(flow==0) d[s]=-1;
return flow;
}
int dinic(int s,int t)
{
int ret=0;
while(bfs(s,t))
{
//        memcpy(cur,head,sizeof(cur));
ret+=dfs(s,t,INF);
}
return ret;
}

int main()
{
int T,kase=0;
int s=0,t=1001;
read(T);
while(T--)
{
int n,m;    // n表示任务总数,m表示点容量
int sum=0;    // sum表示实际所需总时间
read(n),read(m);
init();

for(int i=1; i<=n; i++)
{
int l,p,r;
read(p),read(l),read(r);
sum+=p;
addedge(s,i,p);
for(int j=l; j<=r; j++)
addedge(i,j+500,1);
}
for(int j=1; j<=500; j++)
addedge(j+500,t,m);

printf("Case %d: ",++kase);
if(dinic(s,t)==sum)
puts("Yes");
else    puts("No");
puts("");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: