analysis
是的,这道题是用最短路树(图)做的
要证明(理解)最短路树(图)就是本题的合法答案的话,有下面两种方式
- 假设我们现在有随机的一个方案(n-1条边),那么对于每一个点i,如果它的 d i d_i di在用方案里n-1条边的时候不是最小值的话说明还可以更改路径使得 d i d_i di更小,而最短路树(图)上面的每个点的 d i d_i di都是最小的,因此总和 ∑ d i \sum d_i ∑di也是最小的
- 假设最短路树所给出的方案不是最小的,那么假设有另一个树A使得A给出的方案最小,那么必然有某一点i使得A中的 d i d_i di小于最短路树中的 d i d_i di这与最短路树的定义矛盾
于是先求出最短路树(其实本题中求出的是最短路图(一个DAG),因为最短路树在本题中是不唯一的)
而本题要求输出的是方案总数和具体方案,实质上就是在最短路图中求选择n-1条边的方案数和具体方案,那么根据乘法原理,方案数= ∏ u ∈ [ 1 , n ] f a [ u ] . s i z e ( ) \prod_{u\in[1,n]} fa[u].size() ∏u∈[1,n]fa[u].size()(fa[u].size(),u的可选父节点的个数),输出方案数也就是枚举每一个点的可选边然后打标记罢了
code
#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(int i=start;i<=end;++i)
#define anti_loop(i,start,end) for(register int i=start;i>=end;--i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define ll long long
template<typename T>void read(T &x){
x=0;char r=getchar();T neg=1;
while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
while(r>='0'&&r<='9'){x=(x<<1)+(x<<3)+r-'0';r=getchar();}
x*=neg;
}
int n,m,k;
const int maxn=2e5+10;
const int maxm=2e5+10;
const int maxk=1e5+10;
struct node{
int e;
int w;
int id;
int nxt;
}edge[maxm<<1];
int head[maxn];
int cnt=0;
inline void addl(int u,int v,int id){
edge[cnt].e=v;
edge[cnt].w=1;
edge[cnt].id=id;
edge[cnt].nxt=head[u];
head[u]=cnt++;
}
struct point{
int pos;
int w;
point():pos(0),w(0){}
point(int pos,int w):pos(pos),w(w){}
friend bool operator<(point a,point b){
return a.w>b.w;
}
};
priority_queue<point>q;
int dis[maxn];
int f[maxn];
vector<int>vec[maxn];
inline void dijkstra(int S){
clean(dis,0x3f);
dis[S]=0;
q.push(point(S,0));
while(q.empty()==false){
int f=q.top().pos;
q.pop();
for(int i=head[f];i!=-1;i=edge[i].nxt){
int v=edge[i].e;
if(dis[v]>dis[f]+edge[i].w){
vec[v].push_back(edge[i].id);
dis[v]=dis[f]+edge[i].w;
q.push(point(v,dis[v]));
}
else if(dis[v]==dis[f]+edge[i].w)
vec[v].push_back(edge[i].id);
}
}
}
int usd[maxm];
int tot=1;
int num=0;
void dfs(int dep){
if(dep==n+1){
for(int i=1;i<=m;i++){
printf("%d",usd[i]);
}
printf("\n");
num++;
if(num==tot){
exit(0);
}
return;
}
for(int i=0;i<vec[dep].size();i++){
usd[vec[dep][i]]=1;
dfs(dep+1);
usd[vec[dep][i]]=0;
}
}
int main(){
clean(head,-1);
clean(usd,0);
read(n);
read(m);
read(k);
loop(i,1,m){
int ai,bi;
read(ai);
read(bi);
addl(ai,bi,i);
addl(bi,ai,i);
}
dijkstra(1);
loop(i,2,n){
tot*=vec[i].size();
if(tot>=k){
tot=k;
break;
}
}
printf("%d\n",tot);
dfs(2);
return 0;
}