CF1005F Berland and the Shortest Paths

题目描述:给出一个无向图,找出使每个点离1号距离都有最小值时边的k个选择方案。

题解:

先跑bfs求最短路,然后总方案数*=节点a与深度小于a的点相连边数。

最后枚举每个点连哪条边。

代码:

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 200050
int n,m,k,hed[N],cnt;
struct EG
{
    int to,id,nxt;
}e[2*N];
void ae(int f,int t,int v)
{
    e[++cnt].to = t;
    e[cnt].id = v;
    e[cnt].nxt = hed[f];
    hed[f] = cnt;
}
int dep[N];
bool vis[N];
void dij()
{
    memset(dep,0x3f,sizeof(dep));
    dep[1]=0;
    queue<int>q;
    q.push(1);
    vis[1]=1;
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(!vis[to])
            {
                vis[to]=1;
                dep[to]=dep[u]+1;
                q.push(to);
            }
        }
    }
}
int f[N];
int ans[N],sum=1;
void dfs(int i)
{
    if(i==n+1)
    {
        for(int i=1;i<=m;i++)printf("%d",ans[i]);
        printf("\n");
        sum--;
        if(!sum)exit(0);
    }
    for(int j=hed[i];j;j=e[j].nxt)
    {
        int to = e[j].to;
        if(dep[to]!=dep[i]-1)continue;
        ans[e[j].id]=1;
        dfs(i+1);
        ans[e[j].id]=0;
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int f,t,i=1;i<=m;i++)
    {
        scanf("%d%d",&f,&t);
        ae(f,t,i),ae(t,f,i);
    }
    dij();
    for(int i=2;i<=n;i++)
    {
        int cnt = 0;
        for(int j=hed[i];j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(dep[to]==dep[i]-1)cnt++;
        }
        sum *= cnt;
        if(sum>=k)
        {
            sum=k;
            break;
        }
    }
    printf("%d\n",sum);
    dfs(2);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/LiGuanlin1124/p/9843036.html