hdu 6166(随机概率dijkstra)

题意:要你在一个图指定点钟找出两个距离最短的点

分析:枚举 位数, 使包含当前位数的为一个集合,不包含的为另一个集合,跑dijkstra

#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
#include <vector>
#include <iostream>
using namespace std;
#define maxn 100400
#define INF (1<<30)
typedef long long int ll;
typedef pair<int,int> P;
int T;
int n , m;
bool vis[maxn];
vector<P>E[maxn];
int ans;
int k ;
int kx[maxn];
bool mark[maxn];
int d[maxn];
priority_queue<P,vector<P>,greater<P> >Q;
int dijkstra()
{
    while( !Q.empty() )
    {
        int c = Q.top().first;
        int u = Q.top().second;
        Q.pop();
        if( !mark[u] && vis[u] ){
            return c;
        }
        if( c > d[u] )continue;
        for(int  i = 0 ; i < E[u].size() ; ++i)
        {
            int v = E[u][i].first;
            int w = E[u][i].second;
            if(d[v] > d[u] + w)
            {
                d[v] = d[u] + w;
                Q.push(P(d[v],v));
            }
        }
    }
    return 1e9;
}

void init()
{
     while(!Q.empty())Q.pop();
     for(int i = 0 ; i <= n ; ++i)d[i] = INF;
     for(int i = 1 ; i <= n ; ++i)if( mark[i] )d[i] = 0 , Q.push(P(0,i));

}

int main()
{
    cin >> T;
    int cas = 0;
    while( T-- )
    {
        cin >> n >> m;
        memset(vis,0,sizeof(vis));
        for(int i = 0 ; i <= n ; ++i)E[i].clear();
        for(int i = 0 ; i < m ; ++i)
        {
           int a,b,c;
            scanf("%d %d %d",&a,&b,&c);
            E[a].push_back(P(b,c));
        }
        cin >> k;
        for(int i = 0; i < k ; ++i)scanf("%d",kx+i),vis[kx[i]] = 1;
        printf("Case #%d: ",++cas);
        ans = 1e9;
        for(int i = 1 ; i < 20 ; ++i)
        {
            memset(mark,0,sizeof(mark));
            for(int j = 0 ; j < k ; ++j){
                if( kx[j] & ( 1 << i ) ){
                    mark[kx[j]] = 1;
                }
            }
            init();
            ans = min( ans , dijkstra() );

            memset(mark,0,sizeof(mark));
            for(int j = 0 ; j < k ; ++j){
                if( !( kx[j] & ( 1 << i ) ) ){
                     mark[kx[j]] = 1;
                }
            }
            init();
            ans = min( ans , dijkstra() );
        }
          cout << ans << endl;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值