图论题求助

学术版

ppip @ 2022-12-06 18:47:51

给定一张无向图,求单源最短简单路径。

边权可以为负。


by Itst @ 2022-12-06 19:46:07

NPC 吧


by yizhiming @ 2022-12-06 19:46:12

@ppip 如果简单路径是指没有环的话,那直接跑dij,并在更新距离时判断一下当前被更新距离的节点是否更新过别的节点即可,我没理解错的话是这样的。


by yizhiming @ 2022-12-06 19:47:02

@yizhiming 不对我想错了。。。


by yizhiming @ 2022-12-06 19:49:09

@yizhiming 诶好像没错,简单路径要保证没有经过重复的点,如果我们跑dij的话,就能保证一个点在更新别的点的时候是不经过环的情况下的最小距离,然后我们更新的时候特判就好。


by myee @ 2022-12-06 19:49:22

无向图不清楚,但有向图是 NPC。

有向图取边权全负,就变成了哈密顿路。


by yizhiming @ 2022-12-06 19:57:45

@ppip 我放一下代码,您构造几个数据试试看

直接改的dij模板,就改了两行。

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
#define fr(i,a,b) for(ll i=a;i<=b;i++)
#define dr(i,a,b) for(ll i=a;i>=b;i--)
#define gc(c) c=getchar()
#define pc(c) putchar(c)
#define ll int
ll read()
{
    ll x=0;char c;bool flag=false;gc(c);
    while(c>'9'||c<'0'){if(c=='-')flag=true;gc(c);}
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),gc(c);
    return flag? ~x+1 : x;
}
void pr(ll x)
{
    if(x<0)pc('-'),x=-x;
    if(x>9)pr(x/10);
    pc(x%10+48);
}
const int N=1e5+5,M=2e5+5;
struct edge{int to,w;};
std::vector<edge> G[N];
void add(int u,int v,int w)
{
    G[u].push_back((edge){v,w});
}
int n,m,s;
int dis[N];
bool vis[N];
typedef pair<int,int> pii;
priority_queue<pii>q;
void dijstra(int s)
{
    fr(i,1,n)dis[i]=INT_MAX,vis[i]=0;
    dis[s]=0;q.push(make_pair(0,s));//vis[s]=1;
    while(!q.empty())
    {
        int u=q.top().second;q.pop();
        if(vis[u]){
            continue;
        }
        vis[u] = 1;
        for(int i=0;i<G[u].size();i++)
        {
            int v=G[u][i].to,w=G[u][i].w;
//            if(vis[v])continue;
            if(dis[v]>dis[u]+w&&!vis[v])
            {
                dis[v]=dis[u]+w;
                q.push(make_pair(-dis[v],v));
            }
        }
    }
}
int main()
{
//  freopen("in.txt","r",stdin);
//  freopen("out.txt","w",stdout);
    n=read();m=read();s=read();
    for(int i=1,u,v,w;i<=m;i++)
    {
        u=read();v=read();w=read();
        add(u,v,w);
        add(v,u,w);
    }
    dijstra(s);
    for(int i=1;i<=n;i++)pr(dis[i]),pc(' ');
//  fclose(stdout);
    return 0;
}

这 dij 是我帮别人调的,具体实现哪里有没有问题不太清楚,能过模板题应该问题不大


by ppip @ 2022-12-06 19:59:34

@yizhiming 行


by yizhiming @ 2022-12-06 20:01:08

@yizhiming 草不对,有 bug

过不去

3 3 1

1 2 -1

1 3 -1

2 3 -5

就过不去。。。


by piggy123 @ 2022-12-06 20:04:40

@yizhiming

5 5 1
1 2 -1
2 3 -1
3 4 -1
4 2 -1
1 5 -1

输出的到 5 距离应为-5


by piggy123 @ 2022-12-06 20:04:54

草慢了一步


| 下一页