spfa+枚举 hdu 3768 Shopping

来源:互联网 发布:网络安全法解读—试卷 编辑:程序博客网 时间:2024/05/22 06:05

题意不难理解,n个点组成的m条路,任选s个点,问s个点走一圈的最小路程,先spfa求出s个点相互直接的最短路程,然后DFS一下就行了。

#include <iostream>#include <cstring>#include <cstdio>#include <queue>using namespace std;typedef int weight_t;const int SIZE_E = 200050;const int SIZE_V = 100050;int ECnt = 0;struct edge_t{    int v;    weight_t w;    edge_t *next;}Edge[SIZE_E];edge_t *V[SIZE_V];void mkEdge(int const &a,int const &b,weight_t const &w){    Edge[ECnt].v = b;    Edge[ECnt].w = w;    Edge[ECnt].next = V[a];    V[a] = Edge+ECnt++;    Edge[ECnt].v = a;    Edge[ECnt].w = w;    Edge[ECnt].next = V[b];    V[b] = Edge+ECnt++;}weight_t D[11][SIZE_V];bool flag[SIZE_V];void spfa(int s,int idx){    memset(flag,0,sizeof(flag));    fill(D[idx],D[idx]+SIZE_V,INT_MAX);    D[idx][s] = 0;    flag[s] = true;    queue<int>q;    q.push(s);    while(!q.empty()){        int u = q.front();        q.pop();        flag[u] = false;        for(edge_t *p = V[u];p;p = p->next){            int v = p->v;            weight_t temp = D[idx][u] + p->w;            if (temp < D[idx][v]){                D[idx][v] = temp;                if (!flag[v]){                    flag[v] = true;                    q.push(v);                }            }        }    }}void init(){    ECnt = 0;    memset(V,0,sizeof(V));    memset(Edge,0,sizeof(Edge));}bool vis[11];int need[11];// 从1开始 - sint s;int DFS(int hasVis,int last){    if (hasVis == s) return D[last][0];    int ret = INT_MAX;    for (int i = 1;i <= s;++i){        if (vis[i]) continue;        vis[i] = true;        int tmp = D[last][need[i]];        tmp += DFS(hasVis+1,i);        ret = min(ret,tmp);        vis[i] = false;    }    return ret;}int main(){    int kase ;    scanf("%d",&kase);    while(kase--){        init();        int n,m;        scanf("%d%d",&n,&m);        int x,y,d;        for (int i = 0;i < m;++i){            scanf("%d%d%d",&x,&y,&d);            mkEdge(x,y,d);        }        scanf("%d",&s);        spfa(0,0);        for (int i = 1;i <= s;++i){            scanf("%d",need+i);            spfa(need[i],i);        }        memset(vis,0,sizeof(vis));        printf("%d\n",DFS(0,0));    }    return 0;}


0 0
原创粉丝点击