hdu3986 spfa+枚举

这题让我第一次感受到了什么叫做在绝望中A题。这题我总共交了18次,TLE不知道几次,WA也不知道几次。

这题不能用dijkstra,用这个我一直超时(我没试过dij+优先队列优化,好像优先队列优化后可以过).。

用了我近一天的时间。。。。。。

#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
#define maxn 1002
#define INF 99999999
struct node
{
    int from;
    int to;
    int val;
    int flag;//标记该条边能否使用
    int next;
}a[2*50005];
int index,head[maxn],pre[maxn],n,m,ret,dis[maxn],vis[maxn],mark[maxn];//mark[]用来保存路径的位置
//pre[]来保存路径
void add(int x,int y,int z)
{
    a[index].from=x;
    a[index].to=y;
    a[index].val=z;
    a[index].flag=1;//初始都能使用
    a[index].next=head[x];
    head[x]=index++;
}
void spfa()
{
    int i,j,pos;
    memset(vis,0,sizeof(vis));
    queue<int>q;
    for(i=1;i<=n;i++)
        dis[i]=INF;
    dis[1]=0;
    vis[1]=1;
    q.push(1);
    while(!q.empty())
    {
        int cur=q.front();
        q.pop();
        vis[cur]=0;
        for(i=head[cur];i!=-1;i=a[i].next)
        {
            int v=a[i].to;
            if(a[i].flag&&dis[v]>dis[cur]+a[i].val)//a[].flag标记是否使用
            {
                if(!ret){//ret表示这是第几次spfa,如果第一次,那要记录路径
                    pre[v]=cur;//保存当前点的前一个点
                    mark[v]=i;//保存当前点的位置
                }
                dis[v]=dis[cur]+a[i].val;

                if(!vis[v])
                {
                    q.push(v);
                    vis[v]=1;
                }
            }
        }
    }
}
int main()
{
    int i,j,t,ans;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        index=1;
        memset(head,-1,sizeof(head));
        for(i=0;i<m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        memset(pre,-1,sizeof(pre));
        ret=0;
        spfa();
        ret=1;
        ans=0;
        for(i=n;i!=-1;i=pre[i])
        {
            a[mark[i]].flag=0;//i这里表示点,mark[i]表示点i的位置,a[mark[i]].flag表示点i不能使用
            spfa();
            if(dis[n]>ans)
            {
                ans=dis[n];
            }
            a[mark[i]].flag=1;
        }
        if(ans>=INF)printf("-1\n");
        else printf("%d\n",ans);
    }
}
时间: 2024-08-04 13:02:16

hdu3986 spfa+枚举的相关文章

Zoj 3088 Easter Holidays SPFA+枚举

其实就是枚举最高点和起点,然后以最高点为源点在两张图上分别做spfa.一遍最短路,一遍最长路. 暴露出来的问题:思维不够清晰,代码能力还不够 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include &

zoj2027Travelling Fee(Spfa+枚举)

题目链接: huangjing 题意: 给了起始和终点城市,然后给了若干对城市和距离,然后从起点到终点最小的费用,但是有一个新优惠,那就是费用最大的两个城市之间可以免费. 思路: 最开始以为求了最短路然后减去最大的费用即可.但是想了一组样例就知道是错的. 比如1--->2---->3 然后有直接1----->3,那么如果按刚才的思路,那么最小费用就是2 2     5                  8 所以思路是错的..然后在cp的帮助下得知,既然不知道哪条是最大的费用路,那么我们就

HDU - 3499 Flight 双向SPFA+枚举中间边

Flight Recently, Shua Shua had a big quarrel with his GF. He is so upset that he decides to take a trip to some other city to avoid meeting her. He will travel only by air and he can go to any city if there exists a flight and it can help him reduce

【BZOJ3669】【NOI2014】魔法森林 (spfa动态队列加点算法)

3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MB Submit: 254  Solved: 140 [Submit][Status] Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节点1,隐士则住在号节点N.小E需要通过这一片魔法森林,才能够拜访到隐士. 魔法森林中居住了一些

POJ1062 昂贵的聘礼(带限制的spfa)

Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币.如果你能够弄来他的水晶球,那么只要5000金币就行了."探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格.探险家于是又跑到其他地方,其他人也提出了类似的要求

Day 9.5

T1 可以证明每个点只会走一次 如果遇到环就在环的开始点打上标记 找到可行路的时候回溯,如果回溯时碰到有标记的点就输出Infinity!,否则直接输出ans就行 1 #include <cstdio> 2 int n,a[100010],b[100010],use[100010],in[100010],flag=0,incircle[100010]; 3 char ans[100010]; 4 int dfs(int x,int dep) 5 { 6 if (x<0||x>n-1)

hdu 2962 题解

题目 题意 给出一张图,每条道路有限高,给出车子的起点,终点,最高高度,问在保证高度尽可能高的情况下的最短路,如果不存在输出 $ cannot ?reach ?destination $ 跟前面 $ hdu5418 $ 一样的,题目挺基础的,但是在细节方面比较抠.要是最高度尽可能高,我们就可以想去枚举可能的高度去跑 $ spfa $ ,但我们可以发现这样效率太低了,那么我们为什么不二分答案呢?给出最高高度了,最低不就是 $ 0 $ 吗?二分答案再去跑 $ spfa $ 加上限制条件. 这题时限

【枚举】【SPFA】Urozero Autumn Training Camp 2016 Day 5: NWERC-2016 Problem I. Iron and Coal

那个人派出的队伍的行走的路径一定前半程是重合的,后半程分叉开来. 于是预处理每个点离1号点的最短路,到最近的铁的最短路,到最近的煤的最短路.(三次BFS / SPFA)然后枚举分岔点,尝试更新答案即可. #include<cstdio> #include<queue> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; queue<int>

HDU 5137--How Many Maos Does the Guanxi Worth【枚举 &amp;&amp; 最短路 &amp;&amp; spfa】

How Many Maos Does the Guanxi Worth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submission(s): 847    Accepted Submission(s): 322 Problem Description "Guanxi" is a very important word in Chinese. I