hdu 3768(spfa+暴力)

Shopping

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 758    Accepted Submission(s): 254

Problem Description

You
have just moved into a new apartment and have a long list of items you
need to buy. Unfortunately, to buy this many items requires going to
many different stores. You would like to minimize the amount of driving
necessary to buy all the items you need.

Your city is organized
as a set of intersections connected by roads. Your house and every store
is located at some intersection. Your task is to find the shortest
route that begins at your house, visits all the stores that you need to
shop at, and returns to your house.

Input

The
first line of input contains a single integer, the number of test cases
to follow. Each test case begins with a line containing two integers N
and M, the number of intersections and roads in the city, respectively.
Each of these integers is between 1 and 100000, inclusive. The
intersections are numbered from 0 to N-1. Your house is at the
intersection numbered 0. M lines follow, each containing three integers
X, Y, and D, indicating that the intersections X and Y are connected by a
bidirectional road of length D. The following line contains a single
integer S, the number of stores you need to visit, which is between 1
and ten, inclusive. The subsequent S lines each contain one integer
indicating the intersection at which each store is located. It is
possible to reach all of the stores from your house.

Output

For
each test case, output a line containing a single integer, the length
of the shortest possible shopping trip from your house, visiting all the
stores, and returning to your house.

Sample Input

1
4 6
0 1 1
1 2 1
2 3 1
3 0 1
0 2 5
1 3 5
3
1
2
3

Sample Output

4

Source

University of Waterloo Local Contest 2010.07.10

题意:在100000个点里面选择 <=10个点,然后判断从 0到每个点然后回到 0 所需的最小距离。

题解:坑惨了,spfa的vis数组每次进队列时要赋值为 false....然后就是 spfa+暴力了..

#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long LL;
const LL INF = 999999999999;
const LL N = 100005;
struct Edge{
    LL v,next;
    LL w;
}edge[2*N];
struct City{
    LL id,idx;
}c[20];
LL head[N];
LL tot,n,m,Q;
bool vis[N];
LL low[N];
LL dis[15][15];
LL MIN ;
void addEdge(LL u,LL v,LL w,LL &k){
    edge[k].v = v,edge[k].w = w,edge[k].next = head[u],head[u]=k++;
}
void init(){
    memset(head,-1,sizeof(head));
    tot = 0;
    for(LL i=0;i<15;i++){
        for(LL j=0;j<15;j++){
            dis[i][j] = INF;
        }
    }
}
void spfa(LL pos){
    for(LL i=0;i<n;i++){
        low[i] = INF;
        vis[i] = false;
    }
    low[pos] = 0;
    queue<LL>q;
    q.push(pos);
    while(!q.empty()){
        LL u = q.front();
        q.pop();
        vis[u] = false;  ///!!!!!!!!!!!!!!!!!!
        for(LL k=head[u];k!=-1;k=edge[k].next){
            LL w = edge[k].w,v = edge[k].v;
            if(low[v]>low[u]+w){
                low[v] = low[u]+w;
                if(!vis[v]){
                    vis[v] = true;
                    q.push(v);
                }
            }
        }
    }
}
bool vis1[20];
void dfs(LL u,LL step,LL ans){
    vis1[u] = true;
    if(step==Q){
        MIN = min(MIN,ans+dis[u][0]);
        return;
    }
    for(LL i=0;i<=Q;i++){
        if(!vis1[i]&&dis[u][i]<INF){
            dfs(i,step+1,ans+dis[u][i]);
            vis1[i] = false;
        }
    }

}
int main(){
    int tcase;
    scanf("%d",&tcase);
    while(tcase--){
        init();
        scanf("%lld%lld",&n,&m);
        for(LL i=1;i<=m;i++){
            LL u,v,w;
            scanf("%lld%lld%lld",&u,&v,&w);
            addEdge(u,v,w,tot);
            addEdge(v,u,w,tot);
        }
        scanf("%lld",&Q);
        c[0].id = 0;
        c[0].idx = 0;
        for(LL i=1;i<=Q;i++){
            scanf("%lld",&c[i].id);
            c[i].idx = i;
        }
        for(LL i=0;i<=Q;i++){
            spfa(c[i].id);
            for(LL j=0;j<=Q;j++){
                dis[c[i].idx][c[j].idx] = low[c[j].id];
            }
        }
       /* for(LL i=0;i<=Q;i++){
            for(LL j=0;j<=Q;j++){
                printf("%lld ",dis[i][j]);
            }
            printf("\n");
        }*/
        MIN = INF;
        memset(vis1,false,sizeof(vis1));
        dfs(0,0,0);
        printf("%lld\n",MIN);
    }
    return 0;
}
时间: 2024-10-11 18:50:46

hdu 3768(spfa+暴力)的相关文章

hdu 4876(剪枝+暴力)

题意:给定n,k,l,接下来给出n个数,让你从n个数中选取k个数围成一圈,然后从这k个数中随意选出连续的m(m>=1&&m<=k)个数进行异或后得到[l,r]区间的所有值,让你求最大的r. 分析:关键问题是需要剪枝! 代码实现: #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #inclu

hdu 4499 Cannon(暴力)

题目链接:hdu 4499 Cannon 题目大意:给出一个n*m的棋盘,上面已经存在了k个棋子,给出棋子的位置,然后求能够在这种棋盘上放多少个炮,要求后放置上去的炮相互之间不能攻击. 解题思路:枚举行放的情况,用二进制数表示,每次放之前推断能否放下(会不会和已经存在的棋子冲突),放下后推断会不会互相攻击的炮,仅仅须要对每一个新加入的炮考虑左边以及上边就能够了. #include <cstdio> #include <cstring> #include <algorithm&

HDU 1847(SPFA)

高仿代码: #include <iostream>#include <string.h>#include <queue>#include <vector>#include <utility>#include <cstdio>using namespace std;#define N 205#define M 2005const int inf = 0x3f3f3f3f;int v[M],w[M],next[M],first[N],d[

hdu 4568 spfa 最短路算法+旅行商问题

http://acm.hdu.edu.cn/showproblem.php?pid=4568 Problem Description One day, a hunter named James went to a mysterious area to find the treasures. James wanted to research the area and brought all treasures that he could. The area can be represented a

hdu 5077 NAND(暴力打表)

题目链接:hdu 5077 NAND 题目大意:Xiaoqiang要写一个编码程序,然后根据x1,x2,x3的值构造出8个字符,现在给定要求生成的8个字符,问 说Xiaoqiang最少要写多少行代码.代码内容只能为NAND操作和return操作,操作的变量可以是常数. 解题思路:输入总共就256中情况,所以暴力剪枝打表,打表的代码手贱给删了...所以就将一下思路,开一个s数组 表示变量,然后对应每一层每次两个变量进行NAND操作. 大致三个剪枝,dfs时候,变量出现相同就跳过:8个字符可以直接根

HDU 2112 HDU Today &lt;SPFA算法+map函数&gt;

HDU Today Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 19826    Accepted Submission(s): 4671 Problem Description 经过锦囊相助,海东集团终于度过了危机,从此,HDU的发展就一直顺风顺水,到了2050年,集团已经相当规模了,据说进入了钱江肉丝经济开发区500强.这时候

[BZOJ 1295][SCOI2009]最长距离(SPFA+暴力)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1295 分析:很巧妙的一道spfa从搜索的角度是搜索在所有1中搜索删除哪T个1,对整个图询问,这样肯定TLE 不妨反过来想一想:对于两个点,弄出联通这两个点所需删除的最少的1,那么就知道这两个点是否可以作为题目要求的起点和终点,如果满足算一下结果和ans比较一下就可以. 所以算法就出来了: 枚举起点(S,T),用SPFA跑出图上的所有点到起点这条路径联通的最少删除的1,那么ans=max(di

Shopping(hdu 3768)

题意:给你一个无向图,求从0号点开始遍历所有的指定点再回到0号点的最短路径 #include<cstdio> #include<iostream> #include<queue> #include<algorithm> #include<cstring> #define N 100010 #define ll long long #define INF 10000000000000LL using namespace std; ll head[N

HDU 1874 SPFA/BellmanFord/Dijkstra/Floyd

这题作为模板题,解法好多... 最近周围的人都在搞图论阿,感觉我好辣鸡,只会跟风学习. 暂时只有SPFA的 SPFA (邻接表版.也可以写成临接矩阵存图,但题目可能给出平行边的,所以要注意找最小的边储存,还要注意判断一个点是否多次进入队列)老实说觉得SPFA好像只是被队列优化过的搜索一样的.. 1 #include <stdio.h> 2 #include <algorithm> 3 #include <iostream> 4 #include <string.h