WC 2007 racing jsb 兩題

關於石頭剪刀布和Racing那題題解很清晰,所以就不多說了。

但是,racing這一題竟然卡SPFA,吐槽不能。。。。。。

還有關於racing爲什麼是從賽道上一點走到另一賽道端點而不是中間某點的證明請看題解PPT的第11張(相信很多人都木有認真看題解)

Code

jsb racing(SPFA 60分,懶得改了)

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
bool vis[20005];
int next[2000005],w[2000005],now[20005],head[20005],d[20005],pre[20005],sta[200005],que[200005],c[2000005],link[2000005],n=0,nn=0,m=0,e=1,top=0;
bool spfa()
{
  memset(d,60,sizeof(d));
  memset(vis,0,sizeof(vis));
  memset(pre,0,sizeof(pre));
  int oo=d[0]-1;
  sta[1]=n-1;
  int top=0,tail=1,x=0,y=0,ne=0;
  d[n-1]=0;
  vis[n-1]=1;
  while (top<tail)
    {
      x=sta[++top];
      for (ne=head[x];ne;ne=next[ne])
	if (w[ne] && d[x]+c[ne]<d[link[ne]])
	  {
	    y=link[ne];
	    d[y]=d[x]+c[ne];
	    pre[y]=x;
	    now[y]=ne;
	    if (!vis[y])
	      {
		sta[++tail]=y;
		vis[y]=1;
	      }
	  }
      vis[x]=0;
    }
  if (d[n]<oo) return 1;
  else
    return 0;
}
int getcost()
{
  int nowp=0,flows=1,ctot=0;
  for (nowp=n;nowp!=n-1;nowp=pre[nowp])
    {
      w[now[nowp]]-=flows;
      w[now[nowp]^1]+=flows;
      ctot+=(flows*c[now[nowp]]);
    }
  return ctot;
}
int mincost()
{
  int cost=0;
  while (spfa())
    cost+=getcost();
  return cost;
}
void push(int u,int v)
{
  sta[++top]=u;
  que[top]=v;
}
void add(int u,int v,int ww,int cc)
{
  next[++e]=head[u];
  head[u]=e;
  link[e]=v;
  w[e]=ww;
  c[e]=cc;
  next[++e]=head[v];
  head[v]=e;
  link[e]=u;
  c[e]=-cc;
}
int main()
{
  freopen("jsb.in","r",stdin);
  freopen("jsb.out","w",stdout);
  scanf("%d",&nn);
  int i=0,j=0,tmp=0,mtot=0;
  n=nn;
  for (i=1;i<=nn;i++)
    for (j=1;j<=nn;j++)
      {
	scanf("%d",&tmp);
	if (tmp==1)
	  {
	    d[j]++;
	    mtot++;
	  }
	else
	  if (tmp==2 && i<j)
	    {
	      push(i,j);
	      mtot++;
	    }
      }
  int cost=0;
  for (i=1;i<=nn;i++) 
    cost+=d[i]*d[i];
  int nowd=0;
  for (i=1;i<=top;i++)
    {
      ++n;
      add(n,sta[i],1,0);
      add(n,que[i],1,0);
    }
  for (++n,i=nn+1;i<n;i++)
    add(n,i,1,0);
  for (++n,i=1;i<=nn;i++)
    for (nowd=d[i];nowd<=nn;nowd++)
      add(i,n,1,2*nowd+1);
  cost+=mincost();
  int ans=nn*(nn-1)/2*(nn-2)/3-(cost-mtot)/2;
  printf("%d",ans);
  return 0;
}
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
const double eps=1e-8;
double x[1005*1005],y[1005*1005],w[2005*2005],d[1005*1005];
int next[2005*2005],head[1005*1005],link[1005*1005],c[1005];
int esum=0,node=0,n=0;
double va=0,vb=0;
int sta[4005*4005];
bool vis[1005*1005];
double dis(double x,double y,double xx,double yy)
{
  return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy));
}
int cmp(const void *a,const void *b)
{
  double tmp=x[*(int *)a]+y[*(int *)a]-x[*(int *)b]-y[*(int *)b];
  if (fabs(tmp)<eps)
    return 0;
  else
    if (tmp>0) return 1;
      else return -1;
}
void add(int u,int v,double &vv)
{
  double d=dis(x[u],y[u],x[v],y[v])/vv;
  next[++esum]=head[u];
  head[u]=esum;
  link[esum]=v;
  w[esum]=d;
  next[++esum]=head[v];
  head[v]=esum;
  link[esum]=u;
  w[esum]=d;
}
void dit(double p,double q,double &xx,double &yy,int i,int j)
{
  double left=0,right=1,mid1=0,mid2=0,x1=0,y1=0,x2=0,y2=0,tmp=0,d1=0,d2=0;
  tmp=dis(x[i],y[i],x[i-1],y[i-1])/va;
  while (left+eps<right)
    {
      mid1=left+(right-left)/3;
      mid2=left+(right-left)*2/3;
      x1=x[i-1]+(x[i]-x[i-1])*mid1;
      x2=x[i-1]+(x[i]-x[i-1])*mid2;
      y1=y[i-1]+(y[i]-y[i-1])*mid1;
      y2=y[i-1]+(y[i]-y[i-1])*mid2;
      d1=dis(x[j],y[j],x1,y1)/vb+tmp*(p+q*mid1);
      d2=dis(x[j],y[j],x2,y2)/vb+tmp*(p+q*mid2);
      if (d1<d2)
        right=mid2;
      else
        left=mid1;
    }
  xx=x1;
  yy=y1;
}
int main()
{
  freopen("racing.in","r",stdin);
  freopen("racing.out","w",stdout);
  scanf("%d",&n);++n;
  scanf("%lf%lf",&va,&vb);
  int i=0,j=0;
  for (i=2;i<=n;i++)
    scanf("%lf%lf",&x[i],&y[i]);
  int nn=n,top=0;
  for (i=2;i<=nn;i++)
    {
      top=2;
      c[1]=i-1;c[2]=i;
      for (j=1;j<=nn;j++)
          {
            if (j<i) add(i,j,vb);
            ++n;
            dit(0,1,x[n],y[n],i,j);
            c[++top]=n;
            add(j,n,vb);
            ++n;
            dit(1,-1,x[n],y[n],i,j);
            c[++top]=n;
            add(j,n,vb);
          }
      qsort(c+1,top,sizeof(c[0]),cmp);
      for (j=2;j<=top;j++)
        add(c[j-1],c[j],va);
    }
  int ne=0,xx=0,yy=0;
  d[1]=0;
  for (i=2;i<=n;i++) d[i]=1e10;
  top=0;
  int tail=1;
  sta[1]=1;vis[1]=1;
  while (top<tail)
    {
      xx=sta[++top];
      ne=head[xx];
      while (ne)
        {
          yy=link[ne];
          if (d[yy]>d[xx]+w[ne])
            {
              d[yy]=d[xx]+w[ne];
              if (!vis[yy])
                {
                  sta[++tail]=yy;
                  vis[yy]=1;
                }
            }
          ne=next[ne];
        }
      vis[xx]=0;
    }
  printf("%.6f",d[nn]);
  return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章