[SDOI2010]大陆争霸

带限制的最短路

这道题是我做的第一个带限制的最短路题,所以许多细节我思考了好长时间并看了题解才会的。

首先我们关注条件:机器人无限个,所以我们可以认为有无限个机器人从1号点同时出发。摧毁一个点的代价为max(到达他的代价,破坏他的所有的保护器的代价);所以我们可以开三个数组和一个vector。三个数组分别表示到达该点的代价d1,破坏他的所有的保护器的代价d2,还有他有多少个保护器inde。vector用来存该点保护了哪些点,我一开始想反了。为什么要这样?我们更新摧毁该点的代价时可以更新他保护的城市的d2。最后一遍dij就好了(见代码注释)

code:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<cstring>
#include<vector>
#include<stack>
#define SUPER_INT signed
using namespace std;
const int maxn=400006;
struct hzw
{
    int to,next,v;
}e[maxn];
vector<int>v[maxn];
typedef pair<int,int>p;
int head[maxn],cur,inde[maxn],da[maxn],db[maxn],n,m,k;
inline void add(int a,int b,int c)
{
    e[cur].to=b;
    e[cur].next=head[a];
    e[cur].v=c;
    head[a]=cur++;
}
bool vis[maxn];
inline void dij(int shit)
{
    priority_queue<p,vector<p>,greater<p> >q;
    memset(da,0x3f,sizeof(da));
    da[shit]=0;
    q.push(p(0,shit));
    while (!q.empty())
    {
        p now=q.top();
        q.pop();
        int s=now.second;
        if (vis[s]) continue;
        vis[s]=1;			
		int tmp=max(da[s],db[s]);//破坏这个点实际的代价 
        for (int i=head[s];i!=-1;i=e[i].next)
        {
        	int vv=e[i].to;
        	if (da[vv]>tmp+e[i].v)
        	{
        		da[vv]=tmp+e[i].v;//更新连接的点:到达它需要的代价 
        		if (inde[vv]==0) q.push(p(da[vv],vv)); //如果本来就没有保护器,直接入队 
			}
        }
        for (int i=0;i<v[s].size();++i)
        {
        	int vv=v[s][i];
        	inde[vv]--; 
        	db[vv]=max(db[vv],tmp);//更新该点保护的城市的db值(取max,因为机器人同时出发) 
			if (!inde[vv]) q.push(p(max(db[vv],da[vv]),vv));//如果所保护的城市已经没有保护器了,就入队 
		}
    }
    cout<<max(da[n],db[n]);//good game !  
}
SUPER_INT main()
{
    memset(head,-1,sizeof(head));
	cin>>n>>m;
    for (int i=1,a,b,c;i<=m;++i)
    {
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
    }
    for (int i=1,a;i<=n;++i)
    {
        scanf("%d",&a);
        for (int j=1,b;j<=a;++j)
        {
        	inde[i]++;
            scanf("%d",&b);
            v[b].push_back(i);
        }
    }
    dij(1);
}

收获:

带限制的最短路问题往往有几个条件,就要开几个数组,在跑最短路的过程中不断更新各个参数,注意这类形如xx受到yy,的问题:一般要存yy保护了哪些点,方便更新

posted @ 2018-09-25 15:06  Splitor  阅读(213)  评论(0编辑  收藏  举报