最大流问题
Dinic算法
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
const int maxint=1000001;
int n,m,s,t;
struct edgee
{
int from,to,cap,flow;
};
vector<edgee> edges;
vector<int> G[1003];
bool vis[1003];
int dist[1003];
int cur[1003];
void add(int from,int to,int cap)
{
edges.push_back((edgee){from,to,cap,0});
edges.push_back((edgee){to,from,0,0});
int k=edges.size();
G[from].push_back(k-2);//偶数数为正向弧
G[to].push_back(k-1);
}
int max(int a,int b)
{
return a>b?a:b;
}
int min(int a,int b)
{
return a<b?a:b;
}
bool bfs()
{
memset(vis,0,sizeof(vis));
queue<int> q;
dist[s]=0;
vis[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
int sz=G[u].size();
for(int i=0;i<sz;i++)
{
edgee& e=edges[G[u][i]];
if(!vis[e.to] && e.cap>e.flow)
{
vis[e.to]=1;
dist[e.to]=dist[u]+1;
q.push(e.to);
}
}
}
return vis[t];
}
int dfs(int u,int low)
{
if(u==t || low==0)
return low;
int flow=0,sz=G[u].size(),d;//&引用的妙用
for(int& i=cur[u];i<sz;i++) //正在考虑的最后一条边开始考虑(效率关键)
{
edgee& e=edges[G[u][i]];
if(dist[u]+1==dist[e.to] && (d=dfs(e.to,min(e.cap-e.flow,low)))>0 )
{
e.flow+=d;
edges[G[u][i]^1].flow-=d;
flow+=d;
low-=d;
if(low==0)
break;
}
}
return flow;
}
int Dinic()
{
int flow=0;
while(bfs())
{
memset(cur,0,sizeof(cur));
flow+=dfs(s,maxint);
}
return flow;
}
int main()
{
int T;
int i,j;
int maxn;
int flag=1;
int sum;
cin>>T;
while(T--)
{
sum=0;
int n,m;
maxn=0;
cin>>n>>m;
edges.clear();
for(i=0;i<=1000;i++)
G[i].clear();
for(i=1;i<=n;i++)
{
int pi,ci,ei;
cin>>pi>>ci>>ei;
sum+=pi;
maxn=max(maxn,ei);
add(0,i,pi);
for(j=ci;j<=ei;j++)
add(i,n+j,1);
}
for(i=1;i<=maxn;i++)
add(n+i,maxn+n+1,m);
s=0,t=maxn+n+1;
int tmp=Dinic();
if(sum==tmp)
printf("Case %d: Yes\n\n",flag++);
else
printf("Case %d: No\n\n",flag++);
}
return 0;
}