【提高组】最短路

P1339 [USACO09OCT]热浪Heat Wave

板子题,练习堆优dj。

#include
#define For(i,l,r) for(int i=l;i<=r;i++)
using namespace std;
const int M=6206*2;
int n,m,s,f,head[M],tot,dis[M];
bool vis[M];
typedef pair<int,int> PII;
priority_queue,greater > Q;
struct node{
    int nxt,to,v;
}e[M];
inline void add(int u,int v,int w){
    e[++tot].to=v;
    e[tot].nxt=head[u];
    e[tot].v=w;
    head[u]=tot;
} 
int main(){
    scanf("%d%d%d%d",&n,&m,&s,&f);
    For(i,1,m){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);add(y,x,z);
    }
    memset(dis,0x3f3f3f,sizeof(dis));
    dis[s]=0;Q.push(make_pair(0,s));
    while(!Q.empty()){
        int x=Q.top().second;Q.pop();
        if(vis[x]) continue;
        vis[x]=1;
        for(int i=head[x];i;i=e[i].nxt){
            int to=e[i].to;
            if(dis[to]>dis[x]+e[i].v){
                dis[to]=dis[x]+e[i].v;
                Q.push(make_pair(dis[to],to));
            }
        }
    }
    printf("%d",dis[f]);
    return 0;
}
View Code

 

P1462 通往奥格瑞玛的道路

二分+dj。

#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=10010;
struct pp
{
    int u;
    int v;
    int w;
    int nex;
}e[maxn*maxn];
struct node
{
    int dis;
    int pos;
    bool operator <(const node &x) const
    {
        return x.dis<dis;
    }
};
int dis[maxn],head[maxn],vis[maxn],cost[maxn],f[maxn];
int n,m,b,s,ans,cnt,res,flag,maxl,l,r;
priority_queue  q;
void add(int x,int y,int z)
{
    e[++cnt].u=x;
    e[cnt].v=y;
    e[cnt].w=z;
    e[cnt].nex=head[x];
    head[x]=cnt;
}
bool go( int t)
{

    for(int i=1;i<=n;i++) dis[i]=1000000010,vis[i]=0;
    dis[1]=0;
    q.push((node) {0,1});

    //for(int i=1;i<=n;i++)
    //if(cost[i]>t) vis[i]=1;
    //else vis[i]=0;
    while(!q.empty())
    {
        node tmp=q.top();
        q.pop();
        int x=tmp.pos;
        if(vis[x]) continue;
        vis[x]=1;
        for(int i=head[x];i;i=e[i].nex)
        {
            int y=e[i].v;
            if(dis[y]>dis[x]+e[i].w&&cost[y]<=t)
            {
                dis[y]=dis[x]+e[i].w;
                if(!vis[y])
                q.push((node) {dis[y],y} );

            }
        }
    }
    if(dis[n]return true;
    else return false;

}
int main()
{
    scanf("%d%d%d",&n,&m,&b);
    for(int i=1;i<=n;i++)
    scanf("%d",&f[i]),cost[i]=f[i];
    sort(f+1,f+1+n);
    for(int i=1;i<=m;i++)
    {
        int aa,bb,cc;
        scanf("%d%d%d",&aa,&bb,&cc);
        add(aa,bb,cc);add(bb,aa,cc);
    }
    l=1;r=n;
    if(!go(f[n]+8)) 
    {
        printf("AFK");
        return 0;
    }
    while (l<=r)
    {
        int mid=(l+r)>>1;
        if(go(f[mid])) ans=f[mid],r=mid-1;
        else l=mid+1;

    }
    printf("%d",ans);
    return 0;
}
View Code

 

P1119 灾后重建

很好地考察算法(Floyd)理解的题目。一轮复习时一定要理解算法+充分刷题。同时也提醒了我要重视数据范围

以为比较难,直接往堆优dj想,没认真考虑数据范围,想当然地以为除了堆优dj一定会炸时间(结果堆优炸了),很快想出了一个写法。

结果->改了半天发现没read( )没初始化dis没判断dis1>dis2+w(多打题,精神充沛)->过了样例提交20分,结构体开小了,node记得<<1(还顺手打成了>>)但写成了点而非边->再交40分T了打了个输出优化->50分T了->开了O2T了70分->意识到算法有问题但又懒得想&改了翻题解,哇原来是Floyd。

代码简单又好想。主要难在对Floyd算法的理解与意识到可以用Floyd过。

#include
using namespace std;
const int M=205;
int n,m,a[M],f[M][M];
inline void updata(int k){
    for(int i=0;i){
        for(int j=0;j){
            if(f[i][j]>f[i][k]+f[j][k])
                f[i][j]=f[j][i]=f[i][k]+f[k][j];
        }
    }
    return;
}
int main(){
    cin>>n>>m;
    for(int i=0;i"%d",a+i);
    for(int i=0;i){
        for(int j=0;j){
            f[i][j]=0x3f3f3f3f;
        }
        f[i][i]=0;
    }
    int s1,s2,s3;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&s1,&s2,&s3);
        f[s1][s2]=f[s2][s1]=s3;
    }
    int q,now=0;
    cin>>q;
    for(int i=1;i<=q;i++){
        scanf("%d%d%d",&s1,&s2,&s3);
        while(a[now]<=s3&&now<n){
            updata(now);now++;
        }
        if(a[s1]>s3||a[s2]>s3) cout<<-1<<endl;
        else{
            if(f[s1][s2]==0x3f3f3f3f) cout<<-1<<endl;
            else cout<endl;
        }
    }
    return 0;
} 
View Code

附上Floyd理解好文   https://www.cnblogs.com/GumpYan/p/5540549.html

你可能感兴趣的:(【提高组】最短路)