Berland and the Shortest Paths CodeForces - 1005F(最短路树)

最短路树就是用bfs走一遍就可以了 d[v] = d[u] + 1 表示v是u的前驱边

然后遍历每个结点 存下它的前驱边 再用dfs遍历每个结点 依次取每个结点的某个前驱边即可

#include <bits/stdc++.h>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 1e6+10, INF = 0x7fffffff;

int n, m, k, cnt;
int head[maxn], d[maxn];
vector<int> f[maxn];
vector<string> g;
char str[maxn];
struct node
{
    int u, v, next;
}Node[maxn<<1];

void add_(int u, int v)
{
    Node[cnt].u = u;
    Node[cnt].v = v;
    Node[cnt].next = head[u];
    head[u] = cnt++;
}

void add(int u, int v)
{
    add_(u, v);
    add_(v, u);
}

void init()
{
    mem(head, -1);
    cnt = 0;
}

void dfs(int u)
{
    if(g.size() >= k) return;
    if(u == n+1) { g.push_back(str); return; }
    //cout<< 111 <<endl;
    for(int i=0; i<f[u].size(); i++)
    {
        str[f[u][i]/2] = ‘1‘;
       // cout<< str <<endl;
        dfs(u+1);
        str[f[u][i]/2] = ‘0‘;
    }
}

void bfs(int u)
{
    mem(d, -1);
    queue<int> Q;
    Q.push(u);
    d[u] = 0;
    while(!Q.empty())
    {
        int u = Q.front(); Q.pop();
        for(int i=head[u]; i!=-1; i=Node[i].next)
        {
            node e = Node[i];
            if(d[e.v] == -1)
            {
                d[e.v] = d[u] + 1;
                Q.push(e.v);
            }
        }
    }
}

int main()
{
    init();
    int u, v;
    cin>> n >> m >> k;
    for(int i=0; i<m; i++)
    {
        cin>> u >> v;
        add(u, v);
    }
    bfs(1);
   // cout<< 11 <<endl;
    for(int i=1; i<=n; i++)
    {
        for(int j=head[i]; j!=-1; j=Node[j].next)
            if(d[Node[j].v] + 1 == d[i])
            {
                f[i].push_back(j);
               // cout<< i << "  " << j/2 <<endl;
            }
    }
    for(int i=0; i<m; i++) str[i] = ‘0‘;
    dfs(2);
    cout<< g.size() <<endl;
    for(int i=0; i<g.size(); i++)
    {
        cout<< g[i] <<endl;
    }

    return 0;
}

原文地址:https://www.cnblogs.com/WTSRUVF/p/9637741.html

时间: 2024-08-30 16:06:54

Berland and the Shortest Paths CodeForces - 1005F(最短路树)的相关文章

Codeforces 1005 F - Berland and the Shortest Paths

F - Berland and the Shortest Paths 思路: bfs+dfs 首先,bfs找出1到其他点的最短路径大小dis[i] 然后对于2...n中的每个节点u,找到它所能改变的所有前驱(在保证最短路径不变的情况下),即找到v,使得dis[v] + 1 == dis[u],并把u和v所连边保存下来 最后就是dfs递归暴力枚举每个点的前驱,然后输出答案 #include<bits/stdc++.h> using namespace std; #define fi first

Codeforces 1005F Berland and the Shortest Paths 【最短路树】【性质】

其实是一道裸题,如果没学过最短路树的话会比较难做,要想很久想到关键性质才能做出来. 最短路树顾名思义,就是从一个图中生成出来一棵树,使得每个顶点到root的距离是单源最短路.如果有这样的树的话,那可见这样的树是符合题意的. 怎么生成这样的树呢?关键在于记录前驱father,一个距离root最短路是6的点必定从一个距离root最短路是5的点到达(这两个点之间一定会有一条边).所以我们对于所有顶点 2-n,每个顶点u我们找dis[u] = dis[v]+1的情况,这样的话v就是u的前驱.若v,u之间

CF1005F Berland and the Shortest Paths 最短路树计数

问题描述 LG-CF1005F 题解 由题面显然可得,所求即最短路树. 所以跑出最短路树,计数,输出方案即可. \(\mathrm{Code}\) #include<bits/stdc++.h> using namespace std; template <typename Tp> void read(Tp &x){ x=0;char ch=1;int fh; while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar

The Shortest Statement CodeForces - 1051F(待测试)

#include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> #include <cma

[LeetCode] 244. Shortest Word Distance II 最短单词距离 II

This is a follow up of Shortest Word Distance. The only difference is now you are given the list of words and your method will be called repeatedly many times with different parameters. How would you optimize it? Design a class which receives a list

uva 1416 Warfare And Logistics (最短路树)

uva 1416 Warfare And Logistics Description The army of United Nations launched a new wave of air strikes on terrorist forces. The objective of the mission is to reduce enemy's logistical mobility. Each air strike will destroy a path and therefore inc

UVA 1416 最短路树

Warfare And Logistics The army of United Nations launched a new wave of air strikes on terroristforces. The objective of the mission is to reduce enemy's logistical mobility. Each airstrike will destroy a path and therefore increase the shipping cost

POJ1122_FDNY to the Rescue!(逆向建图+最短路树)

FDNY to the Rescue! Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2368   Accepted: 721 Description The Fire Department of New York (FDNY) has always been proud of their response time to fires in New York City, but they want to make the

HDU - 2433 Travel (最短路树)

题目大意:有N个点,M条边,每次删掉一条边,问删掉该边后,所有点之间的最短路的和是多少 解题思路:刚开始就想,删掉一次floyd一次,结果可想而之,TLE了 后来看了别人的,发现了一种叫做最短路树的东西. 就是先求出以每个点为源点的最短路并纪录该点到每个点的距离和,和每个点的pre,这样的话,就预处理好了 因为要删掉边,前面我们已经预处理好了最短路树的pre,也就是说,就可以依次判断删除的边是否在最短路树上,只要你要删除的边不在该最短路树上,那么就没有影响了,可以直接用前面纪录的数据 如果要删掉