luogu 图论刷题

新年快乐啊!现在感觉原来过年就是找个理由不学习啊!!!!

但是学习还得继续,,,呜呜呜,长期生活在舒适圈别走不出来

p5318
这个题其实考的就是图的遍历(废话),但是存点的时候可以用一个vector把每个点的下一个链接存起来

邻接矩阵可能会爆内存!!!

//
//created by Arc on 2021/2/16
//
//p5318 of luogu
#include<iostream>
#include<vector>
#include <queue>
#include <algorithm>

using namespace std;
struct edge{
    int u;
    int v;
};
vector<int> e[100001];//与第i个点联系的点存在e[i]中
vector<edge> s;
bool cmp(edge a,edge b){
    if(a.u==b.u){
        return a.v<b.v;
    }
    return a.u<b.u;
}
bool vis1[100001]={0};
bool vis2[100001]={0};
void dfs(int x){
    if(vis1[x]==0){
        vis1[x]=1;
        cout<<x<<" ";
        int len=e[x].size();
        for (int i = 0; i < len; ++i) {//遍历e[i]
            dfs(e[x][i]);

        }
    }
}
void bfs(int x ){
    queue<int> q;
    q.push(x);
    vis2[x]=1;
    while(!q.empty()) {
        int now = q.front();
            cout << now<<" ";
            q.pop();
            int len = e[now].size();
            for (int i = 0; i < len; ++i) {
                if (!vis2[e[now][i]]) {
                    q.push(e[now][i]);
                    vis2[e[now][i]]=1;
                }
            }
        }

}
int main(){
    int n,m;
    cin>>n>>m;//n个顶点m条边
    for (int i = 0; i < m; ++i) {
        int vv;
        int uu;
        cin>>uu>>vv;
        s.push_back((edge){uu,vv});

    }
    sort(s.begin(),s.end(),cmp);
    for (int  i = 0; i < m; ++i) {
        e[s[i].u].push_back(s[i].v);
    }
    dfs(1);
    cout<<endl;
    bfs(1);
}

p3916
错误代码:
调试了半天不知道哪错了,,,
其实前面那个店不一定遍历所有的点啊

而且这是个有向图!!!!!!!!!!!!!!!!

再而且,图论你不考虑dfsbfs不是在作死吗?????????

//
//created by Arc on 2021/2/16
//
//p3916 of luogu
#include<iostream>
#include<vector>
#include <queue>
#include <algorithm>

using namespace std;
struct edge{
    int u;
    int v;
};
vector<edge> e;
vector<int> s[10002];
int ans[10002];
bool visited[10012]={0};
bool cmp(edge a,edge b){
    if(a.u==b.u){
        return a.v<b.v;
    }
    return a.u<b.u;
}
int main(){

    int m,n;
    cin>>n>>m;//n points,m edges
    for (int i = 0; i < m; ++i) {
        int x,y;
        cin>>x>>y;
        e.push_back((edge){x,y});
    }
    sort(e.begin(),e.end(),cmp);
    for (int i = 0; i < m; ++i) {//注意这里是可以从零开始的,因为e往里push的时候默认从零
        s[e[i].u].push_back(e[i].v);//这里的s[i]就必须从一开始了,这里就是一个个点了
        s[e[i].v].push_back(e[i].u);
        cout<<e[i].u<<endl;
    }
    for (int i = m-1; i >= 0; --i) {//一开始忘记变--
        int len=s[e[i].u].size();
        for (int j = 0; j < len; ++j) {//这里从哪里遍历一样
            if(!visited[s[e[i].u][j]]){
                visited[s[e[i].u][j]] = true;
                ans[s[e[i].u][j]]=e[i].u;
            }
        }
    }
    for (int i = 0; i < n; ++i) {
        cout<<ans[i];
    }
}

借鉴dl的博客:

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;

#define MAXL 100010

int N, M, A[MAXL];
vector<int> G[MAXL]; //vector存图 

void dfs(int x, int d) {
	if(A[x]) return; //访问过 
	A[x] = d;
	for(int i=0; i<G[x].size(); i++)
		dfs(G[x][i], d);//dfs就可以往里找了
}

int main() {
	int u, v;
	scanf("%d%d", &N, &M);
	for(int i=1; i<=M; i++) {
		scanf("%d%d", &u, &v);
		G[v].push_back(u); //反向建边 
	}
	for(int i=N; i; i--) dfs(i, i); 
	for(int i=1; i<=N; i++) printf("%d ", A[i]);
	printf("\n");
	return 0;
}
posted @ 2021-02-16 21:42  安之若醇  阅读(32)  评论(0编辑  收藏  举报
Live2D服务支持