• 选拔赛-最短路


    还是太菜了吧,,这都不会

    裸的最短路??

    -_-||

    第一种方法:

    每个点有记录两个状态,红灯和绿灯分开记

    抄的牛的代码,spfa。。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 const int maxn=10010;
     7 const int maxe=20010;
     8 const int inf=0x3f3f3f3f;
     9 
    10 int n,m,ss,ee;
    11 int t;
    12 
    13 int dis[maxn][2];  //双状态
    14 int inq[maxn][2];
    15 
    16 struct edge
    17 {
    18     int v,nex;
    19     int a,b;
    20 }e[maxe*2];
    21 
    22 int head[maxn];
    23 int cnt;
    24 void add(int u,int v,int a,int b)
    25 {
    26     e[cnt].v=v;
    27     e[cnt].a=a;
    28     e[cnt].b=b;
    29     e[cnt].nex=head[u];
    30     head[u]=cnt++;
    31 }
    32 
    33 void spfa()
    34 {
    35     queue<int>q;
    36     q.push(ss);
    37     q.push(0);
    38     dis[ss][0]=0;
    39     while(!q.empty())
    40     {
    41         int u=q.front();
    42         q.pop();
    43         int mask=q.front();
    44         q.pop();
    45         inq[u][mask]=0;
    46         for(int i=head[u];i!=-1;i=e[i].nex)
    47         {
    48             int v=e[i].v;
    49             int a=e[i].a;
    50             int b=e[i].b;
    51             int cc=mask?b:a;
    52             int mask2=(cc&1)^mask;   // 位运算很巧妙!!
    53             if(dis[v][mask2]>dis[u][mask]+cc)
    54             {
    55                 dis[v][mask2]=dis[u][mask]+cc;
    56                 if(!inq[v][mask2])
    57                 {
    58                     inq[v][mask2]=1;
    59                     q.push(v);
    60                     q.push(mask2);
    61                 }
    62             }
    63         }
    64     }
    65 }
    66 
    67 int main()
    68 {
    69     int T;
    70     int u,v,a,b;
    71     scanf("%d",&T);
    72     while(T--)
    73     {
    74         scanf("%d%d%d%d",&n,&m,&ss,&ee);
    75         for(int i=0;i<=n;i++) head[i]=-1;
    76         cnt=0;
    77         memset(inq,0,sizeof(inq));
    78         memset(dis,0x3f3f3f,sizeof dis);
    79         for(int i=0;i<m;i++)
    80         {
    81             scanf("%d%d%d%d",&u,&v,&a,&b);
    82             add(u,v,a,b);
    83             add(v,u,a,b);
    84         }
    85         spfa();
    86         int ans=min(dis[ee][0],dis[ee][1]);
    87         if(ans==inf) puts("-1");
    88         else printf("%d
    ",ans);
    89     }
    90 }

    第二种方法:

    拆点。。

    对每个点 x拆成两个点 2x,2x+1  分别表示绿灯状态和红灯状态。
    对于绿灯奇数时间的路线 a,b 连接  2a2b+1 和 2b2a+1,其他路线类似。
    最后跑一遍标准的 SPFA 即可

    今天好累,不想打了,先直接贴上吧。。

     1 #include<bits/stdc++.h>
     2 #define IN(x) (x<<1)
     3 #define OUT(x) (x<<1|1)
     4 using namespace std;
     5 
     6 const int maxn=10000*2+10;
     7 const int INF=~0U>>2;
     8 
     9 struct edge{int from,to,dis;};
    10 
    11 struct SPFA{
    12     int n;
    13     vector<int>G[maxn];
    14     vector<edge>E;
    15     int d[maxn];
    16     bool vis[maxn];
    17     
    18     void init(int n){
    19         this->n=n;
    20         for(int i=0;i<=n;i++)G[i].clear();
    21         E.clear();
    22     }
    23 
    24     void addedge(int from,int to,int dis){
    25         E.push_back((edge){from,to,dis});
    26         G[from].push_back(E.size()-1);
    27     }
    28 
    29     void exec(int S){
    30         for(int i=0;i<=n;i++)d[i]=INF,vis[i]=0;
    31         d[S]=0,vis[S]=1;
    32         queue<int>Q;
    33         Q.push(S);
    34         while(!Q.empty()){
    35             int x=Q.front();
    36             Q.pop();vis[x]=0;
    37             for(int i:G[x]){
    38                 edge &e=E[i];
    39                 if(d[e.to]>d[e.from]+e.dis){
    40                     d[e.to]=d[e.from]+e.dis;
    41                     if(!vis[e.to]){
    42                         vis[e.to]=1;
    43                         Q.push(e.to);
    44                     }
    45                 }
    46             }
    47         }
    48     }
    49 
    50     int value(int x){return d[x];}
    51 }app;
    52 
    53 
    54 
    55 int main(){
    56     int T;
    57     scanf("%d",&T);
    58     while(T--){
    59         int n,m,s,t;
    60         scanf("%d%d%d%d",&n,&m,&s,&t);
    61         s--,t--;
    62         app.init(n*2);
    63         for(int i=1;i<=m;i++){
    64             int a,b,c,d;
    65             scanf("%d%d%d%d",&a,&b,&c,&d);
    66             a--,b--;
    67             app.addedge(IN(a),IN(b)^(c&1),c);
    68             app.addedge(IN(b),IN(a)^(c&1),c);
    69             app.addedge(OUT(a),OUT(b)^(d&1),d);
    70             app.addedge(OUT(b),OUT(a)^(d&1),d);
    71         }    
    72         app.exec(IN(s));
    73         printf("%d
    ",min(app.value(IN(t)),app.value(OUT(t))));
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    修改ASP.NET MVC Ajax分页组件ASP.NET MvcPager一个小Bug并修该样式为自己所用(一)
    HighCharts报表 API
    自动化开发资料
    修改ASP.NET MVC Ajax分页组件ASP.NET MvcPager一个小Bug并修该样式为自己所用(三)
    网络营销资料收集
    C#扩展方法
    UI Automation Under the Hood (1)
    C#辅助类之ConfigHelper
    设计模式资源汇总
    Windows GUI自动化测试
  • 原文地址:https://www.cnblogs.com/yijiull/p/6711314.html
Copyright © 2020-2023  润新知