• cdoj 秋实大哥带我飞 最短路走法 含0权边


    //做完这题以后终于理解白书上的边为什么要那样定义了 可以很方便的在o(1) 时间内找到反向边

    解法:先跑一边最短路,然后检查最短路上有没有0权边(dfs就好,但是每条边只能走一次,这里就需要用异或找反向边),最后记忆化搜索一遍(每条边也是只能走一次)

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<queue>
      8 #include<vector>
      9 #include<map>
     10 #include<stack>
     11 #include<string>
     12 
     13 using namespace std;
     14 
     15 const int INF=1000000000;
     16 const int MOD=1000000009;
     17 
     18 struct Edge{
     19     int from,to,cost;
     20 };
     21 
     22 vector <Edge> edges;
     23 vector <int> G[2007];
     24 bool vis[4000007];
     25 int dis[2007];
     26 bool inq[2007];
     27 int f[2007];
     28 int n,m;
     29 
     30 void AddEdge(int x,int y,int z){
     31     edges.push_back((Edge){x,y,z});
     32     edges.push_back((Edge){y,x,z});
     33     int sz=edges.size();
     34     G[x].push_back(sz-2);
     35     G[y].push_back(sz-1);
     36 }
     37 
     38 void SPFA(){
     39     dis[1]=0;
     40     memset(inq,0,sizeof(inq));
     41     queue<int>q;
     42     q.push(1);
     43     inq[1]=1;
     44     while (!q.empty()){
     45             int now=q.front();
     46             int sz=G[now].size();
     47             q.pop();
     48             for (int i=0;i<sz;i++){
     49                             Edge& e=edges[G[now][i]];
     50                             if (dis[e.to]>dis[now]+e.cost){
     51                                     dis[e.to]=dis[now]+e.cost;
     52                                     if (!inq[e.to]){
     53                                             q.push(e.to);
     54                                             inq[e.to]=1;
     55                                     }
     56                             }
     57             }
     58             inq[now]=0;
     59     }
     60 }
     61 
     62 bool check(int now){
     63     if (now==1) return 1;
     64     bool flag=1;
     65     int sz=G[now].size();
     66     for (int i=0;i<sz;i++){
     67             Edge& e=edges[G[now][i]];
     68             if (!vis[G[now][i]] && dis[now]==dis[e.to]+e.cost){
     69                     vis[G[now][i]]=1;
     70                     vis[G[now][i]^1]=1;
     71                     if (e.cost==0) flag=false;
     72                     if (!check(e.to)) flag=false;
     73             }
     74     }
     75     return flag;
     76 }
     77 
     78 int work(int now){
     79     if (f[now]!=-1) return f[now];
     80     f[now]=0;
     81     int sz=G[now].size();
     82     for (int i=0;i<sz;i++){
     83             Edge& e=edges[G[now][i]];
     84             if (!vis[G[now][i]] && dis[now]==dis[e.to]+e.cost){
     85                     vis[G[now][i]]=1;
     86                     vis[G[now][i]^1]=1;
     87                     f[now]=(f[now]+work(e.to))%MOD;
     88             }
     89     }
     90     return f[now];
     91 }
     92 
     93 
     94 int main(){
     95     scanf("%d%d",&n,&m);
     96     for (int i=1;i<=n;i++) dis[i]=INF;
     97     for (int i=0;i<m;i++){
     98             int x,y,z;
     99             scanf("%d%d%d",&x,&y,&z);
    100             AddEdge(x,y,z);
    101     }
    102     SPFA();
    103     //printf("%d
    ",dis[n]);
    104     memset(vis,0,sizeof(vis));
    105     if (!check(n)){
    106             printf("-1
    ");
    107             return 0;
    108     }
    109     memset(vis,0,sizeof(vis));
    110     memset(f,-1,sizeof(f));
    111     f[1]=1;
    112     printf("%d
    ",work(n));
    113     return 0;
    114 }
    115 /*
    116 4 4
    117 1 2 1
    118 1 3 1
    119 2 4 2
    120 3 4 2
    121 
    122 4 4
    123 1 2 0
    124 1 3 1
    125 2 4 99
    126 3 4 99
    127 */
    View Code
  • 相关阅读:
    yii之behaviors
    查看windows系统信息
    idm chrome扩展被阻止解决办法
    音乐乐理基础
    bootstrap4
    七牛上传整合CI
    提升上传速度
    卡漫绘图
    指针的操作
    定语从句八个易混淆
  • 原文地址:https://www.cnblogs.com/baby-mouse/p/4534335.html
Copyright © 2020-2023  润新知