codeforces 1005F dfs+bfs+思维

F. Berland and the Shortest Paths
time limit per test
5 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

There are nn cities in Berland. Some pairs of cities are connected by roads. All roads are bidirectional. Each road connects two different cities. There is at most one road between a pair of cities. The cities are numbered from 11 to nn.

It is known that, from the capital (the city with the number 11), you can reach any other city by moving along the roads.

The President of Berland plans to improve the country's road network. The budget is enough to repair exactly n1n−1 roads. The President plans to choose a set of n1n−1 roads such that:

  • it is possible to travel from the capital to any other city along the n1n−1 chosen roads,
  • if didi is the number of roads needed to travel from the capital to city ii, moving only along the n1n−1 chosen roads, then d1+d2++dnd1+d2+⋯+dn is minimized (i.e. as minimal as possible).

In other words, the set of n1n−1 roads should preserve the connectivity of the country, and the sum of distances from city 11 to all cities should be minimized (where you can only use the n1n−1 chosen roads).

The president instructed the ministry to prepare kk possible options to choose n1n−1 roads so that both conditions above are met.

Write a program that will find kk possible ways to choose roads for repair. If there are fewer than kk ways, then the program should output all possible valid ways to choose roads.

Input

The first line of the input contains integers nn, mm and kk (2n2105,n1m2105,1k21052≤n≤2⋅105,n−1≤m≤2⋅105,1≤k≤2⋅105), where nn is the number of cities in the country, mm is the number of roads and kk is the number of options to choose a set of roads for repair. It is guaranteed that mk106m⋅k≤106.

The following mm lines describe the roads, one road per line. Each line contains two integers aiai, bibi (1ai,bin1≤ai,bi≤n, aibiai≠bi) — the numbers of the cities that the ii-th road connects. There is at most one road between a pair of cities. The given set of roads is such that you can reach any city from the capital.

Output

Print tt (1tk1≤t≤k) — the number of ways to choose a set of roads for repair. Recall that you need to find kk different options; if there are fewer than kk of them, then you need to find all possible different valid options.

In the following tt lines, print the options, one per line. Print an option as a string of mm characters where the jj-th character is equal to '1' if the jj-th road is included in the option, and is equal to '0' if the road is not included. The roads should be numbered according to their order in the input. The options can be printed in any order. All the tt lines should be different.

Since it is guaranteed that mk106m⋅k≤106, the total length of all the tt lines will not exceed 106106.

If there are several answers, output any of them.

Examples
Input
Copy
4 4 3
1 2
2 3
1 4
4 3
Output
Copy
2
1110
1011
Input
Copy
4 6 3
1 2
2 3
1 4
4 3
2 4
1 3
Output
Copy
1
101001
Input
Copy
5 6 2
1 2
1 3
2 4
2 5
3 4
3 5
Output
Copy
2
111100
110110

题意:给你一个无向图,1为起点,建立一个最小生成树让起点到其他个点的距离最小,如果有比k大的方案数输出k种方案,如果比k小就输出全部,每一种方案的每一条边用了为1没用为0,输出。

思路:好多人在求最小生成树的时候用的dij或spfa来求最短路,但是我就得没必要,直接以1为起点bfs为深度,这样跑出来的深度就是最小生成树,然后dfs答案,这个操作十分巧妙,步骤为:当起点为 st 可以到达的所有点 en 满足dep[st]==dep[en]+1;那么en点一定是st点的上层点 en点一定要连接到上层点,但不一定是st点把这条边的id记录,让后dfs每一个点可能的每一条边具体看代码

#include<stdio.h>
#include<string.h>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<set>
#include<map>
#define ll long long
#define qq printf("QAQ\n");
using namespace std;
const int maxn=1e5+5;
const int inf=2e9+1e8+1234;
const ll linf=8e18+9e17;
const int mod=1e9+7;
const double e=exp(1.0);
const double pi=acos(-1);
struct node{
	int to,id;
};
vector<node>v[maxn<<1];
vector<int>v1[maxn<<1];
vector<string>v2;
int dep[maxn<<1]={0},ans,num,n,k;
string s;
void bfs()
{
	queue<int>q;
	q.push(1);
	dep[1]=1;
	//v1[1].push_back(1);
	while(!q.empty())
	{
		int now=q.front();
		q.pop();
		num=max(num,dep[now]);
		for(int i=0;i<v[now].size();i++)
		{
			int next=v[now][i].to;
			if(!dep[next])
			{
			//s[v[now][i].id]='1';
			dep[next]=dep[now]+1;
			
			//v1[dep[next]].push_back((node){next,v[now][i].id});
			
			q.push(next);
			}
		}
	}
}
void dfs(int st)
{
	if(v2.size()>=k)return ;
	if(st>n)
	{
		v2.push_back(s);
		return ;
	}
	for(int i=0;i<v1[st].size();i++)
	{
		s[v1[st][i]]='1';
		dfs(st+1);
		s[v1[st][i]]='0';
	}
}
int main()
{
	int m;
	while(scanf("%d%d%d",&n,&m,&k)!=EOF)
	{
		int st,en;
		s.clear();
		for(int i=0;i<m;i++)
		{
			s+='0';
			scanf("%d%d",&st,&en);
			v[st].push_back((node){en,i});
			v[en].push_back((node){st,i});
		}
		ans=1,num=0;
		bfs();
		for(int i=2;i<=n;i++)
		{
			for(int j=0;j<v[i].size();j++)
			{
				int next=v[i][j].to;
				if(dep[i]==dep[next]+1)v1[i].push_back(v[i][j].id);
			}
		}
		dfs(2);
		printf("%d\n",v2.size());
		for(int i=0;i<v2.size();i++)
		cout<<v2[i]<<endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值