CF1005F Berland and the Shortest Paths (树上构造最短路树)

题目大意:给你一个边权为$1$的无向图,构造出所有$1$为根的最短路树并输出

性质:单源最短路树上每个点到根的路径 ,一定是这个点到根的最短路之一

边权为$1$,$bfs$出单源最短路,然后构建最短路树即可

代码实现需要思考

可以用$vector$记录最短路树中,每个点可能的父亲,对于合法父亲数量$>1$的点,$dfs$出所有可能的方案

 1 #include <queue>
 2 #include <vector>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <algorithm>
 6 #define N 200100
 7 #define ll long long
 8 using namespace std;
 9 
10 int T;
11 int n,m,K,cte;
12 int head[N],dis[N];
13 struct Edge{int to,nxt;}edge[N*2];
14 void ae(int u,int v){
15     cte++;edge[cte].nxt=head[u];
16     head[u]=cte,edge[cte].to=v;
17 }
18 vector<int>fa[N];
19 void bfs()
20 {
21     queue<int>q;
22     memset(dis,0x3f,sizeof(dis));
23     dis[1]=0;q.push(1);
24     int tot=1;
25     while(!q.empty())
26     {
27         int u=q.front();q.pop();
28         for(int j=head[u];j;j=edge[j].nxt){
29             int v=edge[j].to;
30             if(dis[v]>dis[u]+1){
31                 dis[v]=dis[u]+1;
32                 fa[v].push_back(j);
33                 q.push(v);
34             }else if(dis[v]==dis[u]+1){
35                 fa[v].push_back(j);
36             }
37         }
38     }
39 }
40 int now[N],ans[N],sum,stk[N],tp;
41 ll tot;
42 void dfs_ans(int i)
43 {
44     if(i>tp){
45         for(int i=1;i<=m;i++)
46             printf("%d",ans[i]);
47         puts("");sum++;
48         if(sum>=tot) exit(0);
49         return;
50     }
51     int u=stk[i];
52     now[u]=0;
53     for(;now[u]<fa[u].size();now[u]++){
54         ans[fa[u][now[u]]>>1]=1;
55         dfs_ans(i+1);
56         ans[fa[u][now[u]]>>1]=0;
57     }
58 }
59 void solve()
60 {
61     bfs();tot=1;
62     for(int i=2;i<=n;i++){
63         int w=fa[i].size();
64         tot*=1ll*max(1,w);
65         if(tot>K) break;
66     }tot=min(1ll*K,tot);
67     printf("%lld\n",tot);
68     for(int i=2;i<=n;i++)
69     {
70         if(fa[i].size()>1)
71             stk[++tp]=i;
72         else ans[fa[i][0]>>1]=1;
73     }
74     dfs_ans(1);
75 }
76 
77 
78 int main()
79 {
80     freopen("t1.in","r",stdin);
81     scanf("%d%d%d",&n,&m,&K);
82     int x,y;cte=1;
83     for(int i=1;i<=m;i++)
84         scanf("%d%d",&x,&y),ae(x,y),ae(y,x);
85     solve();
86     return 0;
87 }

猜你喜欢

转载自www.cnblogs.com/guapisolo/p/9880889.html