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 #define se second #define pi acos(-1.0) #define LL long long #define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<int,pii> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 2e5 + 5; int n, m, k; vector<pii>g[N]; vector<int>pre[N]; int dis[N]; bool vis[N]; char s[N]; vector<string>res; void bfs(int st) { queue<pii>q; dis[1] = 0; vis[1] = true; q.push({1, 0}); while(!q.empty()) { pii p = q.front(); q.pop(); for (int i = 0; i < g[p.fi].size(); i++) { int v = g[p.fi][i].fi; if(!vis[v]) { vis[v] = true; dis[v] = p.se + 1; q.push({v, p.se + 1}); } } } } void dfs(int u) { if((int) res.size() >= k) return ; if(u > n) { res.pb(s+1); return ; } for (int i = 0; i < pre[u].size(); i++) { s[pre[u][i]] = '1'; dfs(u+1); s[pre[u][i]] = '0'; } } int main() { fio; int u, v; cin >> n >> m >> k; for (int i = 1; i <= m; i++) { cin >> u >> v; g[u].pb({v, i}); g[v].pb({u, i}); } bfs(1); for (int i = 2; i <= n; i++) { for (int j = 0; j < g[i].size(); j++) { pii p = g[i][j]; if(dis[p.fi]+1 == dis[i]) pre[i].pb(p.se); } } for (int i = 1; i <= m; i++) s[i] = '0'; dfs(2); cout << (int)res.size() << endl; for (int i = 0; i < res.size(); i++) cout << res[i] << endl; return 0; }