WA求助,Dinic算法
查看原帖
WA求助,Dinic算法
527070
XiaoZi_qwq楼主2023/9/10 18:17

如题,在部分数据点中输出比标准输出较小 内附注释,有劳大佬们指出一下问题所在

提交详情

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
using namespace std;
inline int read()
{
  register int x=0,f=1;
  char c;c=getchar();
  while(c<'0' || '9'<c)
    f=(c=='-') ? -1:f,c=getchar();
  while('0'<=c && c<='9')
    x=x*10+c-'0',c=getchar();
  return x*f;
}
const int N=945*15+200,s=0,t=945*15+100;
int n,m,k,num,h[N],tr[30][30],sz[30],len[30],day;
struct flow
{
  int from,to,flow,cap;
}f[4*N];
void insert(int from,int to,int flow,int cap)
{
  f[++num].from=h[from];
  f[num].to=to;
  f[num].flow=flow;
  f[num].cap=cap;
  h[from]=num;
}
void add(int f,int t,int c)
{
  insert(f,t,0,c);
  insert(t,f,0,0);
}
//建图
bool connect[30];//防止hack的无可奈何之举
void build()
{
  //printf("At %d time\n",day);
  add(s,day*n+2,inf);//源点到地球
  add(day*n+1,t,inf);//月球到汇点
  //飞船
  memset(connect,0,sizeof(connect));
  for(int i=1;i<=m;i++)
  {
    int nw=(day-1)%len[i];
    add((day-1)*n+tr[i][nw],day*n+tr[i][nw+1],sz[i]);
    if(tr[i][nw]==tr[i][nw+1]) connect[tr[i][nw]]=true;
    //printf("[Add] %d(T%d) => %d(T%d)\n",tr[i][nw],day-1,tr[i][nw+1],day);
  }
  //原地不动
  for(int i=1;i<=n;i++)
  {
    if(connect[i]) continue;
    add((day-1)*n+i,day*n+i,inf);
    //printf("[Add] %d(T%d) => %d(T%d)\n",i,day-1,i,day);
  }
}
//网络流
bool vis[N];
int maxflow,d[N];
queue<int> q;
bool bfs()
{
  q.push(s);
  memset(vis,0,sizeof(vis));
  vis[s]=true;
  while(!q.empty())
  {
    int u=q.front();q.pop();
	for(int i=h[u];i;i=f[i].from)
	  if(f[i].flow<f[i].cap && vis[f[i].to]==false)
	   d[f[i].to]=d[u]+1,vis[f[i].to]=true,q.push(f[i].to);    
  }
  return vis[t];
}
int dfs(int u,int flow)
{
  if(u==t || flow==0) return flow;
  int final,num=0;
  for(int i=h[u];i;i=f[i].from)
    if(d[u]+1==d[f[i].to] && (final=dfs(f[i].to,min(flow,f[i].cap-f[i].flow)))>0)
	{
	  f[i].flow+=final;
	  f[i^1].flow-=final;
	  num+=final;
	  flow-=final;
	}
  return num;
}
int main()
{
   n=read(),m=read(),k=read();
   n+=2;//1月2地
   for(int i=1;i<=m;i++)
   {
     sz[i]=read(),len[i]=read();
     for(int j=0;j<=len[i]-1;j++) tr[i][j]=read()+2;
     tr[i][len[i]]=tr[i][0];
   }
   add(s,day*n+2,inf);//源点到地球
   add(day*n+1,t,inf);//月球到汇点
   while(maxflow<k && day<=945)
   {
     day++;
     build();
     while(bfs())
     {
       maxflow+=dfs(s,inf);
     }
   }
   if(maxflow>=k) cout<<day;
   else cout<<0;
   return 0;
}
2023/9/10 18:17
加载中...