题目大意:给你一个边权为$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 }