Codeforces Round #621 (Div.1+Div.2) D-Cow and Fields 链式前向星+dijkstra+堆优化”


#include<iostream>
#include<string.h>
#include<algorithm>
#include<queue>
#define Head head
using namespace std;
const int maxn=2e6+10,mod=1e9+7;
int n,m,dis[maxn];
struct node
{
    
    
    int to,w,next;
}edge[maxn<<2];
int head[maxn], tot;
void init()
{
    
    
    memset(head,-1,sizeof(head));
    memset(dis,0x3f3f3f3f,sizeof(dis));
    tot = 0;
}
void addEdge(int u,int v,int w)
{
    
    
    edge[tot].to = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot ++;
}
struct cmp
{
    
    
    //优先队列的排序函数;
    bool operator()(int &a,int &b)const
    {
    
    
        return dis[a]> dis[b];
    }
};
void dijkstra(int Dis[],int x)
{
    
    
    //用优先队列寻找Dis[]最小点;
    //代替遍历搜索,节约时间;
    priority_queue<int,vector<int>,cmp > q;
    Dis[x]= 0;
    q.push(x);                       //将x 加入队列,涂成灰色;
    while (! q.empty())
    {
    
    
        int u= q.top();
        q.pop();                     //将x 出队列,涂成白色;
        for (int k= Head[u]; k!= -1; k= edge[k].next )
        {
    
    
            int v= edge[k].to;
            if (Dis[v]> Dis[u]+ edge[k].w )
            {
    
    
                Dis[v]= Dis[u]+ edge[k].w;
                q.push(v);           //将x+ 1加入队列,涂成灰色;
            }
        }
    }
}

int read() {
    
    
    int x = 0, w = 1;
    char ch = 0;
    while (ch < '0' || ch > '9') {
    
      // ch 不是数字时
        if (ch == '-') w = -1;        // 判断是否为负
        ch = getchar();               // 继续读入
    }
    while (ch >= '0' && ch <= '9') {
    
      // ch 是数字时
        x = x * 10 + (ch - '0');  // 将新读入的数字’加’在 x 的后面
        // x 是 int 类型,char 类型的 ch 和 ’0’ 会被自动转为其对应的
        // ASCII 码,相当于将 ch 转化为对应数字
        // 此处也可以使用 (x<<3)+(x<<1) 的写法来代替 x*10
        ch = getchar();  // 继续读入
    }
    return x * w;  // 数字 * 正负号 = 实际数值
}

long long qpow(long long a,long long b,long long c)//a^b%c
{
    
    
    long long ans=1;
    long long k=a;
    while(b>0)
    {
    
    
        if(b % 2 == 1)
            ans=(ans*k)%c;
        k=(k*k)%c;
        b=b/2;
    }
    return ans;
}


int main()
{
    
    
    //dijkstra+链式前向星
    n=read();
    m=read();
    //n个顶点 m条边
    init();
    for(int i=0;i<m;i++){
    
    
        int u,v;
        u=read();
        v=read();
        addEdge(u,v,1);
        addEdge(v,u,1);
    }
    dijkstra(dis,1);
    long long ans=0;
    for(int i=2;i<=n;i++){
    
    
        int k=dis[i];
        ans=(ans%mod+qpow(2,k,mod))%mod;//2^k%mod
    }
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_56336619/article/details/115033315