https://www.luogu.org/problemnew/show/P3371
https://www.luogu.org/problemnew/show/P4779
这两道题都是有向图,改成无向图也很简单,读入边的时候当做无向边处理就好了。没有测试朴素版的迪杰斯特拉,看数据范围O(n^2)应该是会超时的吧。
给出代码:
#include<iostream>
#include<cstdio>
#include<stack>
#include<cmath>
#include<cstring>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=100005;
int n,m;
int vis[maxn],dis[maxn];
struct Edge
{
int to; //尾结点
int value; //权值
};
vector<Edge> edge[200005];
struct node
{
int id;
int w;
bool operator < (const node&b)const //距离小的在前面
{
return w>b.w;
}
};
void Dijkstra(int s); //传入起点
int main()
{
int s;
scanf("%d%d%d",&n,&m,&s);//顶点数 边数 起点
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
Edge e;
e.to=y; //尾结点
e.value=z; //距离
edge[x].push_back(e);
}
Dijkstra(s);
for(int i=1;i<=n;i++)
{
if(dis[i]!=INF)
printf("%d ",dis[i]);
else
printf("2147483647 ");//不可达
}
return 0;
}
void Dijkstra(int s)
{
memset(vis,0,sizeof(vis));
memset(dis,INF,sizeof(dis));
priority_queue<node> q;
node a;
a.id=s,a.w=0;
q.push(a);
dis[s]=0; //起始结点
while(!q.empty())
{
node now=q.top();
q.pop();
int id=now.id;
if(vis[id])
continue;
vis[id]=1;
for(int i=0;i<edge[id].size();i++)
{
int nxt=edge[id][i].to;
if(!vis[nxt]&&dis[id]+edge[id][i].value<dis[nxt])
{
dis[nxt]=dis[id]+edge[id][i].value;
node temp;
temp.id=nxt;
temp.w=dis[nxt];
q.push(temp);
}
}
}
}