图论一

复健Day7(图论一)

1.单源最短路的建图方式

1.香甜的黄油

https://www.acwing.com/problem/content/description/1129/

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define maxn 810
#define int long long
#define inf 0x3f3f3f3f
using namespace std;

int n,p,c;

struct Edge
{
	int v,dis,nxt;
	Edge(){}
	Edge(int v,int dis,int nxt):v(v),dis(dis),nxt(nxt){}
}ed[maxn<<2];

int tot,head[maxn];

int dis[maxn],pos[maxn],vis[maxn];

void add(int u,int v,int w)
{
	ed[tot]=Edge(v,w,head[u]);
	head[u]=tot++;
}

struct Node
{
	int v,dis;
	Node(){}
	Node(int v,int dis):v(v),dis(dis){}
	bool operator < (const Node &rhs) const{
		return dis>rhs.dis;
	}
};

void Dij(int s)
{
	for(int i=1;i<=p;i++) dis[i]=inf;
	memset(vis,0,sizeof(vis));
	dis[s]=0;
	priority_queue<Node> q;
	q.push(Node(s,0));
	while(!q.empty())
	{
		Node t=q.top();
		int u=t.v;
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=head[u];~i;i=ed[i].nxt)
		{
			int v=ed[i].v;
			if(dis[v]>dis[u]+ed[i].dis)
			{
				dis[v]=dis[u]+ed[i].dis;
				q.push(Node(v,dis[v]));
			}
		}
	}
}

int read()
{
	int ans=0,f=1;char i=getchar();
	while(i<'0'||i>'9'){if(i=='-') f=-1;i=getchar();}
	while(i>='0'&&i<='9'){ans=ans*10+i-'0';i=getchar();}
	return ans*f;
}

signed main()
{
	memset(head,-1,sizeof(head));
	n=read();p=read();c=read();
	for(int i=1;i<=n;i++) pos[i]=read();
	for(int i=1;i<=c;i++)
	{
		int u,v,w;
		u=read();v=read();w=read();
		add(u,v,w);add(v,u,w);
	}
	int ans=inf;
	for(int i=1;i<=p;i++)
	{
		Dij(i);
		int sum=0;
		bool flag=true;
		for(int j=1;j<=n;j++)
		{
			if(dis[pos[j]]==inf)
			{
				flag=false;
				break;
			}
			sum+=dis[pos[j]];
		}
		if(flag&&sum<ans) ans=sum;
	}
	printf("%d\n",ans);
	return 0;
}

就是非常简单的Dijkstra模板,因为我们的堆优化Dijkstra的复杂度是O(nlogn),然后我们枚举终点,最终复杂度为O(nplogn),是1e8多的复杂度可以通过,当然你也可以通过一些读写优化来降低复杂度

2.最优乘车

https://www.acwing.com/problem/content/description/922/

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<sstream>
#define maxn 510
#define inf 0x3f3f3f3f
using namespace std;

string line;
vector<int> sz[maxn];
queue<int> q;
int s;
int dis[maxn];
int stop[maxn];

void bfs()
{
	int ans=0;
	q.push(1);
	dis[1]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(int i=0;i<sz[u].size();i++)
		{
			int v=sz[u][i];
			if(dis[v]>dis[u]+1)
			{
				dis[v]=dis[u]+1;
				q.push(v);
			}
		}
	}
}

int main()
{
	int m,n;
	cin>>m>>n;
	for(int i=1;i<=n;i++) dis[i]=inf;
	getline(cin,line);
    while(m--)
	{
        getline(cin,line);
        stringstream ss(line);
        int p,cnt=0;
        while(ss>>p) stop[++cnt]=p;
        for(int i=1;i<=cnt;i++)
        {
            for(int j=i+1;j<=cnt;j++)
			{
				sz[stop[i]].push_back(stop[j]);
            }
        }
    }
    bfs();
	if(dis[n]==inf) printf("NO\n");
	else printf("%d\n",max(dis[n]-1,0));
	return 0;
}

这道题的BFS部分还是比较模板的,主要的问题出在输入的部分,可以认真学习一下getline,stringstream这几个函数的作用

posted on   dolires  阅读(4)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示