求一个图最短路边的办法。好像下面的那个有问题。单向边和双向边一定是有区别的。这个比较容易。参照该文的最短路网络流题目和连通图题目一题求最短路关节边

另外上述2个题目的代码好像有问题。

在UVALIVE 6885中不能得到AC。不知道原因。感觉是对的。

另一种判断最短路的方法就是

从起点到u+从终点到v+边U,V权值==最短路值那么这条边为最短路

这种方案的代码

for (int i = 1 ; i <= M ; i++) {
            scanf("%d%d%d",&u[i],&v[i],&w[i]);
            u[i]++;v[i]++;
            S.add_edge(u[i],v[i],w[i],i);
            S.add_edge(v[i],u[i],w[i],i);
            T.add_edge(u[i],v[i],w[i],i);
            T.add_edge(v[i],u[i],w[i],i);
        }
        S.dijkstra(source);
        T.dijkstra(target);
        long long ans = 0;
        for (int i = 1 ; i <= P ; i++) {
            for (int j = S.head[i] ; j != -1 ; j = S.edge[j].next) {
                int v = S.edge[j].v;
                if (S.dis[i] + T.dis[v] + S.edge[j].w == S.dis[target])
                    //这条边为最短路边
            }
        }

同时另一种可能存在问题的方法如下

 for (int i = 1 ; i <= m ; i++)
        {
            scanf("%d%d%I64d",&u[i],&v[i],&w[i]);
            S.add_edge(u[i],v[i],w[i],i);
            S.add_edge(v[i],u[i],w[i],i);
            T.add_edge(u[i],v[i],w[i],i);
            T.add_edge(v[i],u[i],w[i],i);
        }
        S.dijkstra(s);
        T.dijkstra(t);
        init();
        for (int i = 1 ; i <= m ; i++)
        {
            int tu = u[i];
            int tv = v[i];
            LL tw = w[i];
            if ((S.dis[tu] + tw == S.dis[tv] && T.dis[tv] + tw == T.dis[tu])
                ||(S.dis[tv] + tw == S.dis[tu] && T.dis[tu] + tw == T.dis[tv]))
            {
                add_edge(tu,tv,tw,i);
                add_edge(tv,tu,tw,i);//这里是为了处理tarjan无向图 其实就是u[i],v[i],w[i]这条边为最短路边。
            }
        }
        slove(n);

对于上述方案的有向图 建图有区别

如下

 

for (int i = 0 ; i < M ; i++)
        {
            scanf("%d%d%d",&u[i],&v[i],&w[i]);
            St.add_edge(u[i],v[i],w[i],i + 1);
            //St.add_edge(v[i],u[i],w[i],i + 1);
            //Ted.add_edge(u[i],v[i],w[i],i + 1);
            Ted.add_edge(v[i],u[i],w[i],i + 1);
        }
        scanf("%d%d",&A,&B);
        St.dijkstra(A);
       /* if (St.dis[B] == INF)
        {
            puts("0");
            continue;
        }
        */
        Ted.dijkstra(B);
        for (int i = 0 ; i < M ; i++)
        {
            int tu = u[i];
            int tv = v[i];
            int tw = w[i];
            if (tu == tv) continue;
            if ((St.dis[tu] + tw == St.dis[tv] && Ted.dis[tv] + tw == Ted.dis[tu])
                ||(St.dis[tv] + tw == St.dis[tu] && Ted.dis[tu] + tw == Ted.dis[tv]))
            {
                add_edge(tu,tv,1);//这里添加的是网络流的边无需双向
            }
        }

 

POJ 2387 Til the Cows Come Home

直接求最短路末班题。我这里是dijkstra+优先队列优化的班

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 4100;
const int MAXM = 40005;
const int INF = 0x3f3f3f3f;
struct Edge
{
    int u,v,next;
    int w;
}edge[MAXM];
int head[MAXN],tot;

void init()
{
    tot = 0;
    memset(head,-1,sizeof(head));
}

void add_edge(int u,int v,int w)
{
    edge[tot].u = u;
    edge[tot].v = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot++;
}

struct heapnode
{
    int val,u;
    bool operator < (const heapnode &rhs) const
    {
        return val > rhs.val;
    }
};

bool done[MAXN];
int dis[MAXN];
priority_queue<heapnode>q;
int N,M;

void dijkstra(int s)
{
    memset(done,false,sizeof(done));
    while (!q.empty()) q.pop();
    memset(dis,0x3f,sizeof(dis));
    dis[s] = 0;
    q.push((heapnode){dis[s],s});
    while (!q.empty())
    {
        heapnode x = q.top(); q.pop();
        int u = x.u;
        if (done[u]) continue;
        done[u] = true;
        for (int i = head[u] ; i != -1 ; i = edge[i].next)
        {
            int v = edge[i].v;
            if (dis[v] > dis[u] + edge[i].w)
            {
                dis[v] = dis[u] + edge[i].w;
                q.push((heapnode){dis[v],v});
            }
        }
    }
}

int main()
{
    while (scanf("%d%d",&N,&M) != EOF)
    {
        swap(N,M);
        init();
        for (int i = 0 ; i < M ; i++)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add_edge(u,v,w);
            add_edge(v,u,w);
        }
        dijkstra(1);
        printf("%d\n",dis[N]);
    }
    return 0;
}
View Code

相关文章:

  • 2021-07-23
  • 2018-10-24
  • 2022-12-23
  • 2021-11-24
  • 2022-12-23
  • 2022-12-23
  • 2021-12-22
  • 2021-11-17
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-29
  • 2022-12-23
  • 2022-12-23
  • 2021-11-05
相关资源
相似解决方案