BZOJ 1001 狼追兔子 平面图最大流

本文深入探讨了Dijkstra算法的应用及实现细节,通过具体实例讲解如何使用该算法解决最短路径问题,并介绍了算法中的关键数据结构和操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//为什么点数都要乘以2呢?

//还是默默的学一下dij吧;;
//s.t的摆放是为什么???


#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<algorithm>
#define maxn 2000100
#define maxm 6000000
#define inf 0x3f3f3f
using namespace std;
int em;
int head[maxn];
int d[maxn];
bool vis[maxn];

struct Edge
{
    int u,v,w,next;
}edge[maxm];

void add(int u,int v,int w)
{
    edge[em].u=u;
    edge[em].v=v;
    edge[em].w=w;
    edge[em].next=head[u];
    head[u]=em++;
   // cout<<u<<" "<<v<<" "<<w<<" de  "<<endl;
}

struct data
{
    int d;int u;
    data(int a,int b):u(a),d(b){}
    bool operator < (const data &T) const{ return d>T.d;}
};


priority_queue <data>q;
void dij(int s,int t)
{
    for(int i=0;i<=t+1;i++)
        d[i]=inf;
    memset(vis,false,sizeof(vis));
    while(!q.empty()) q.pop();
    q.push(data(s,0)); d[s]=0;
    while(!q.empty())
    {
        int u=q.top().u;
        q.pop();
        if(vis[u]) continue;
        if(u==t) {cout<<d[t]<<endl;return;}
        vis[u]=1;
        for(int i=head[u];~i;i=edge[i].next)
        {
            int v=edge[i].v;
            if(!vis[v]&& d[v]>d[u]+edge[i].w)
            {
                d[v]=d[u]+edge[i].w;
                q.push(data(v,d[v]));
            }
        }
      //  cout<<d[t]<<endl;
    }
}


int xx,yy,z,n,m,miao;
//哪一块为s,t什么的是为什么?
int main()//哦、、我忘了他的每一个正方形被分为两块,所以要*2什么的。。
{
//    freopen("input.txt","r",stdin);
    while(scanf("%d%d",&n,&m)!=EOF)
    {
       // cout<<n<<" "<<m<<endl;
       if(n==1 && m==1) {printf("0\n");continue;}
        if(n==1||m==1)
        {
            int ans=inf;
            if(n<m) swap(n,m);
            for(int i=1;i<=n;i++)
                scanf("%d",&miao),ans=min(ans,miao);
            cout<<ans<<endl;
            continue;
        }
        //cout<<"miao"<<endl;
    em=0;memset(head,-1,sizeof(head));
    int s=0;int t=(n-1)*(m-1)*2+1;
     for(int i=1;i<=n;i++)
            for(int j=1;j<=m-1;j++)
            {
                scanf("%d",&z);
                xx=((i-2)*(m-1)+j)*2;
                yy=((i-1)*(m-1)+j)*2-1;
                if(i==1) xx=t;
                if(i==n) yy=s;//为什么这里要反呢?
                add(xx,yy,z);
                add(yy,xx,z);
            }
    for(int i=1;i<=n-1;i++)
        for(int j=1;j<=m;j++)
        {
        scanf("%d",&z);
        xx=((i-1)*(m-1)+j-1)*2-1;
        yy=((i-1)*(m-1)+j)*2;
        if(j==1) xx=s;
        if(j==m) yy=t;//这个s,t 是怎么弄得?
        add(xx,yy,z);
        add(yy,xx,z);
        }
    for(int i=1;i<=n-1;i++)
        for(int j=1;j<=m-1;j++)
    {
        scanf("%d",&z);
        xx=((i-1)*(m-1)+j)*2;
        yy=((i-1)*(m-1)+j)*2-1;
        add(xx,yy,z);
        add(yy,xx,z);
    }
    dij(s,t);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值