• HDU 3313 Key Vertex(dfs + bfs)


    HDU 3313 Key Vertex

    题目链接

    题意:一个有向无环图。求s,t之间的割点

    思路:先spfa找一条最短路出来,假设不存在。就n个都是割点。


    然后每次从s进行dfs,找到能经过最短路上的最远点。然后这个点就是割点。然后下次在以这个为起点dfs,不断迭代直到找到t为止

    代码:

    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <queue>
    #include <algorithm>
    using namespace std;
    
    const int N = 100005;
    
    int n, m, s, t, fa[N], vis[N], mark[N], d[N];
    int first[N], vv[N * 3], next[N * 3], en;
    
    const int INF = 0x3f3f3f3f;
    
    void addedge(int a, int b) {
    	vv[en] = b;
    	next[en] = first[a];
    	first[a] = en++;
    }
    
    bool bfs() {
    	queue<int> Q;
    	for (int i = 0; i < n; i++) d[i] = INF;
    	memset(vis, 0, sizeof(vis));
    	Q.push(s);
    	vis[s] = 1;
    	d[s] = 0;
    	while (!Q.empty()) {
    		int u = Q.front();
    		vis[u] = 0;
    		Q.pop();
    		for (int i = first[u]; i + 1; i = next[i]) {
    			int v = vv[i];
    			if (d[v] > d[u] + 1) {
    				d[v] = d[u] + 1;
    				fa[v] = u;
    				if (!vis[v]) {
    					Q.push(v);
    					vis[v] = 1;
    				}
    			}
    		}
    	}
    	if (d[t] >= INF) return false;
    	int tmp = t;
    	memset(mark, 0, sizeof(mark));
    	while (tmp != s) {
    		mark[tmp] = 1;
    		tmp = fa[tmp];
    	}
    	mark[s] = mark[t] = 1;
    	return true;
    }
    
    void dfs(int u) {
    	for (int i = first[u]; i + 1; i = next[i]) {
    		int v = vv[i];
    		if (vis[v]) continue;
    		vis[v] = 1;
    		if (mark[v]) {
    			if (d[v] > d[s])
    				s = v;
    			continue;
    		}
    		dfs(v);
    	}
    }
    
    int main() {
    	while (~scanf("%d%d", &n, &m)) {
    		memset(first, -1, sizeof(first));
    		en = 0;
    		int u, v;
    		while (m--) {
    			scanf("%d%d", &u, &v);
    			addedge(u, v);
    		}
    		scanf("%d%d", &s, &t);
    		if (!bfs()) {
    			printf("%d
    ", n);
    			continue;
    		}
    		int ans = 1;
    		memset(vis, 0, sizeof(vis));
    		while (s != t) {
    			dfs(s);
    			ans++;
    		}
    		printf("%d
    ", ans);
    	}
    	return 0;
    }


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    C语言中scanf()的用法
    Android学习笔记——Day3
    Android学习笔记——Day6
    Android学习笔记——Day5
    Android学习笔记——Day4
    Android学习笔记——Day2
    一个计时器按钮
    直方图均衡
    拉普拉斯算子进行图像边缘提取
    在jframe上显示超大号的文字
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4678071.html
Copyright © 2020-2023  润新知