zoukankan      html  css  js  c++  java
  • CF 360E Levko and Game——贪心

    题目:http://codeforces.com/contest/360/problem/E

    官方题解与证明:http://codeforces.com/blog/entry/9529

    一条可以调整的边的边权要么是 l [ i ] 要么是 r[ i ] 。

    先把所有可调整边设成 r[ i ] ,然后看看有没有一条可调整的边 (x,y)满足 dis1[x]<=dis2[x] 且其边权还是 r[ i ];如果有,就把它改成 l [ i ]。

    改完一条边之后就再做一遍 dij( ) ,然后再改;直到没有可改的边。

    其实每次可以不止改一条边,可以把能改的边都改了。因为据证明,一条边 (x,y) 如果 dis1[x]<=dis2[x] ,不会在之后某次修改别的边的时候变成 dis1[x]>dis2[x] 了;所以一旦能改,就一直能改,所以一次改很多能改的边也是可以的。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define ll long long
    using namespace std;
    const int N=1e4+5,M=105;
    int n,m,t,hd[N],xnt,bh[M],l[M],r[M],s1,s2,F;
    ll dis1[N],dis2[N];bool vis[N],ans[M];
    priority_queue<pair<ll,int> > q;
    struct Ed{
      int x,to,nxt,w;
      Ed(int f=0,int a=0,int b=0,int c=0):x(f),to(a),nxt(b),w(c) {}
    }ed[N+M];
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    void add(int x,int y,int z){ed[++xnt]=Ed(x,y,hd[x],z);hd[x]=xnt;}
    void dj()
    {
      memset(dis1,0x3f,sizeof dis1);dis1[s1]=0;
      memset(vis,0,sizeof vis);
      q.push(make_pair(0,s1));
      while(q.size())
        {
          int k=q.top().second;q.pop();
          if(vis[k])continue;vis[k]=1;
          for(int i=hd[k],v;i;i=ed[i].nxt)
        if(dis1[v=ed[i].to]>dis1[k]+ed[i].w)
          dis1[v]=dis1[k]+ed[i].w,q.push(make_pair(-dis1[v],v));
        }
      memset(dis2,0x3f,sizeof dis2);dis2[s2]=0;
      memset(vis,0,sizeof vis);
      q.push(make_pair(0,s2));
      while(q.size())
        {
          int k=q.top().second;q.pop();
          if(vis[k])continue;vis[k]=1;
          for(int i=hd[k],v;i;i=ed[i].nxt)
        if(dis2[v=ed[i].to]>dis2[k]+ed[i].w)
          dis2[v]=dis2[k]+ed[i].w,q.push(make_pair(-dis2[v],v));
        }
    }
    int main()
    {
      n=rdn();m=rdn();t=rdn();
      s1=rdn();s2=rdn();F=rdn();
      for(int i=1,u,v,z;i<=m;i++)
        u=rdn(),v=rdn(),z=rdn(),add(u,v,z);
      for(int i=1,u,v;i<=t;i++)
        {
          u=rdn();v=rdn();l[i]=rdn();r[i]=rdn();
          add(u,v,r[i]); bh[i]=xnt;
        }
      bool flag;
      while(1)
        {
          dj();flag=0;
          for(int i=1,d;i<=t;i++)
        {
          d=bh[i];
          if(ed[d].w==l[i]||dis1[ed[d].x]>dis2[ed[d].x])continue;
          ed[d].w=l[i];ans[i]=1;flag=1;
        }
          if(!flag)break;
        }
      dj();
      if(dis1[F]>dis2[F]){puts("LOSE");return 0;}
      if(dis1[F]==dis2[F])puts("DRAW"); else puts("WIN");
      for(int i=1;i<=t;i++)printf("%d ",ans[i]?l[i]:r[i]);puts("");
      return 0;
    }
  • 相关阅读:
    硬盘的结构和介绍,硬盘MBR详细介绍(超详细彩图)
    websocket协议学习
    Qt4可以使用trUtf8函数,其内容可以是中文,也可以是F硬编码
    QString转换为LPTSTR(使用了reinterpret_cast,真是叹为观止,但是也开阔了思路),三篇文章合起来的各种转换方法
    系统高可用
    Visual Studio
    管道是如何建立起来的?
    CLR和.Net对象
    任务调度
    路由与控制器
  • 原文地址:https://www.cnblogs.com/Narh/p/10135605.html
Copyright © 2011-2022 走看看