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

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

    首先,每条边不是选 ( l[i] ) 就是选 ( r[i] );

    做法就是先把边权都设成 ( r[i] ),然后做 ( dijkstra ),如果有一条可改的边 ( (a,b) ) 而且 ( dis1[a] < dis2[a] ),那么就改边权为 ( l[i] );

    然后重复这个过程直到无边可改;

    因为要考虑平局,所以只要 ( dis1[a] <= dis2[a] ) 就改,这样先让第一个人的路是最优的;

    其实也不用一条一条改,一次改所有能改的就行,因为据题解的证明,一次改了一条边后,不会使一个 ( dis1[a] <= dis2[a] ) 的边突然变得 ( dis1[a] > dis2[a] )

    题解的证明...看不动了...感性理解...

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long ll;
    int const xn=1e4+105,xm=105;
    int n,m,cnt,hd[xn],ct,to[xn],nxt[xn],w[xn],s1,s2,f;
    ll dis[2][xn],inf=1e17;
    bool vis[xn];
    struct E{int u,v,bh,l,r,w;}ed[xm];
    struct N{
      ll d; int id;
      N(ll d=0,int i=0):d(d),id(i) {}
      bool operator < (const N &y) const
      {return d>y.d;}
    };
    priority_queue<N>q;
    int rd()
    {
      int ret=0,f=1; char ch=getchar();
      while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return f?ret:-ret;
    }
    void add(int x,int y,int z){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct; w[ct]=z;}
    void dij(int t)
    {
      for(int i=1;i<=n;i++)dis[t][i]=inf;
      for(int i=1;i<=n;i++)vis[i]=0;
      int st=(t?s2:s1);
      dis[t][st]=0; q.push(N(0,st));
      while(q.size())
        {
          int x=q.top().id; q.pop();
          if(vis[x])continue; vis[x]=1;
          for(int i=hd[x],u;i;i=nxt[i])
        if(dis[t][u=to[i]]>dis[t][x]+w[i])
          {
            dis[t][u]=dis[t][x]+w[i];
            q.push(N(dis[t][u],u));
          }
        }
    }
    int main()
    {
      n=rd(); m=rd(); cnt=rd();
      s1=rd(); s2=rd(); f=rd();
      for(int i=1,x,y,z;i<=m;i++)x=rd(),y=rd(),z=rd(),add(x,y,z);
      for(int i=1;i<=cnt;i++)
        ed[i].u=rd(),ed[i].v=rd(),ed[i].l=rd(),ed[i].r=rd(),
          ed[i].bh=ct+1,ed[i].w=1,add(ed[i].u,ed[i].v,ed[i].r);
      dij(0); dij(1);
      while(dis[0][f]>=dis[1][f])
        {
          int i;
          for(i=1;i<=cnt;i++)
        if(dis[0][ed[i].u]<=dis[1][ed[i].u]&&ed[i].w)break;
          if(i>cnt)
        {
          if(dis[0][f]>dis[1][f])puts("LOSE"); 
          else 
            {
              puts("DRAW");
              for(int j=1;j<=cnt;j++)printf("%d ",ed[j].w?ed[j].r:ed[j].l);
              puts("");
            }
          return 0;
        }
          ed[i].w=0; w[ed[i].bh]=ed[i].l; dij(0); dij(1);
        }
      puts("WIN");
      for(int j=1;j<=cnt;j++)printf("%d ",ed[j].w?ed[j].r:ed[j].l);
      puts("");
      return 0;
    }
  • 相关阅读:
    八款常用的 Python GUI 开发框架推荐
    scrapy + mogoDB 网站爬虫
    tkinter界面卡死的解决办法
    通过核心API启动单个或多个scrapy爬虫
    爬虫怎样绕过验证码?
    Python爬虫入门教程 33-100 电影评论数据抓取 scrapy
    Python开发 之 Websocket 的使用示例
    StringBuffer详解
    其实python正则表达式就这样简单明了
    ABAP和Java里的单例模式攻击
  • 原文地址:https://www.cnblogs.com/Zinn/p/10135585.html
Copyright © 2011-2022 走看看