K - Candies (spfa+stack+拆分约束)

请问spfa+stack 和spfa+queue 是什么原理

2014年03月19日 15:52:49

阅读数:472

一个是bfs加迭代

一个是dfs加迭代

请问迭代是什么

就是不断地做,做到没有更优的解为止

或者是不断得做,做到逼近答案为止。。

栈比队列更快更节省空间

有的时候有的图可能比较稀疏而且点数较多,邻接矩阵存不下,所以就要用到邻接表。邻接表用vector数组比较方便,但是vector比较慢。所以就有了链式向前星。



#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

//链式向前星其实就是有n链表,每条链表存的是所有相同结点的边。




const int maxn=1100;//点数
const int maxm=11000;//边数
struct xx
{
    int next,n,to;
} node[maxm]; //每个结点存一条边,next表示与当前边起点一样的另一条边在弄的数组中的位置。to表示这条边的终点,n表示这条边的权值。
int head[maxn];//head[i]表示从i出发的点的链表的第一个点在node数组中的位置。
int num=0;//当前已有边的个数。
void Add(int from,int to,int n)
{
    node[num].to=to;
    node[num].n=n;
    node[num].next=head[from];//当前结点指向以前的头结点
    head[from]=num++;//当前结点变为头结点
}
void Use(int i)//遍历起点为i的链表
{
    int t=head[i];
    while(t!=-1)
    {
        cout<<"from "<<i<<"to "<<node[t].to<<"is "<<node[t].n<<endl;
        t=node[t].next;
    }
}
int main()
{
    int from,to,n;
    memset(head,-1,sizeof(head));
    memset(node,-1,sizeof(node));
    while(cin>>from>>to>>n,from&&to&&n)
    {
        Add(from,to,n);
    }
    int i;
    cin>>i;
    Use(i);
}
这是一题典型的差分约束题。不妨将糖果数当作距离,把相差的最大糖果数看成有向边AB的权值,
我们得到 dis[B]-dis[A]<=w(A,B)。看到这里,我们联想到求最短路时的松弛技术,
即if(dis[B]>dis[A]+w(A,B), dis[B]=dis[A]+w(A,B)。
即是满足题中的条件dis[B]-dis[A]<=w(A,B),由于要使dis[B] 最大,
所以这题可以转化为最短路来求。
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 30005
#define maxm 150005
int n,m,x,y,z;
int dis[maxn];
int head[maxn];
bool vis[maxn];
struct node
{
    int nextone,w,v;
} edge[maxm];
int num=0;//当前已有边的个数。
void Add(int from,int to,int w)
{
    edge[num].v=to;
    edge[num].w=w;
    edge[num].nextone=head[from];
    head[from]=num++;
}
void spfa()
{
    memset(vis,0,sizeof(vis));
    for(int i=1; i<=n; i++)
        dis[i]=inf;
    dis[1]=0;
    stack <int>stk;
    stk.push(1);
    vis[1]=0;
    while(!stk.empty())
    {
        int temp=stk.top();
        stk.pop();
        vis[temp]=0;
        int idx=head[temp];
        while(idx!=-1)
        {
            if(dis[edge[idx].v]>dis[temp]+edge[idx].w)
            {
                dis[edge[idx].v]=dis[temp]+edge[idx].w;
                if(!vis[edge[idx].v])
                {
                stk.push(edge[idx].v);
                vis[edge[idx].v]=1;
                }
            }
            idx=edge[idx].nextone;
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    memset(head,-1,sizeof(head));
   scanf("%d%d",&n,&m);
    while(m--)
    {
        scanf("%d%d%d",&x,&y,&z);
        Add(x,y,z);
    }
    spfa();
    printf("%d\n",dis[n]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/BePosit/article/details/81410986