F. Berland and the Shortest Paths
题意:一张图有n个顶点,m条边,现在要求选择n-1条边,输出<=k个方案.
每个方案满足:顶点1到任何1个顶点的距离 总和 最小.
思路:每个顶点(除了1),有选择1条边的机会.先bfs求出1到所有顶点的最短距离,假如 dis[u]==dis[v]+1 其中v为相邻顶点,则选这条边,能够最小化答案.那么对于u来说,选择(u,v1) (u,v2) (u,v3)同样能最小化答案.假如问答案有多少种,直接乘起来,这里只要求至多k组,并且k*t<=1e6
#include<bits/stdc++.h>
#define PI acos(-1.0)
#define pb push_back
#define F first
#define S second
using namespace std;
typedef long long ll;
const int N=2e5+5;
const int MOD=1e9+7;
ll a[N],sum[N];
int n,m,k;
int dis[N];
vector<pair<int,int> >edge[N];
vector<int> can[N];
void bfs(int st){
for(int i=1;i<=n;i++) dis[i]=1e9+9;
queue <int> q;
dis[1]=0;
q.push(1);
while(!q.empty()){
int u=q.front();
q.pop();
for(auto t : edge[u]){
int v=t.F;
if(dis[u]+1<dis[v]){
dis[v]=dis[u]+1;
q.push(v);
}
}
}
return ;
}
char res[N];
vector<string> ans;
void dfs(int u){
if((int)ans.size()>=k) return ;
if(u==n+1){ ans.pb(res+1);
return ;
}
for(auto t:can[u]){
res[t]='1';
dfs(u+1);
res[t]='0';
}
return ;
}
int main(void){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >>n >>m >>k ;
for(int i=1;i<=m;i++){
int u,v;
cin >>u>>v;
edge[u].pb({v,i});
edge[v].pb({u,i});
}
bfs(1);
// cout <<"here"<<endl;
for(int u=2;u<=n;u++){
for(auto t : edge[u]){
int v=t.F;
if(dis[u]==dis[v]+1){
can[u].pb(t.S);
}
}
}
for(int i=1;i<=m;i++) res[i]='0';
dfs(2);
cout << (int)ans.size()<<endl;
for(int i=0;i<(int)ans.size();i++){
cout << ans[i]<<endl;
}
return 0;
}