• 【BZOJ1924】【SDOI2010】所驼门王的宝藏(Tarjan,SPFA)


    题目描述

    在宽广的非洲荒漠中,生活着一群勤劳勇敢的羊驼家族。被族人恭称为“先知”的Alpaca L. Sotomon是这个家族的领袖,外人也称其为“所驼门王”。所驼门王毕生致力于维护家族的安定与和谐,他曾亲自率军粉碎河蟹帝国主义的野蛮侵略,为族人立下赫赫战功。所驼门王一生财宝无数,但因其生性节俭低调,他将财宝埋藏在自己设计的地下宫殿里,这也是今天Henry Curtis故事的起点。Henry是一个爱财如命的贪婪家伙,而又非常聪明,他费尽心机谋划了这次盗窃行动,破解重重机关后来到这座地下宫殿前。

    整座宫殿呈矩阵状,由R×C间矩形宫室组成,其中有N间宫室里埋藏着宝藏,称作藏宝宫室。宫殿里外、相邻宫室间都由坚硬的实体墙阻隔,由一间宫室到达另一间只能通过所驼门王独创的移动方式——传送门。所驼门王为这N间藏宝宫室每间都架设了一扇传送门,没有宝藏的宫室不设传送门,所有的宫室传送门分为三种:

    “横天门”:由该门可以传送到同行的任一宫室;
    
    “纵寰门”:由该门可以传送到同列的任一宫室;
    “自*河蟹*由*河蟹*门”:由该门可以传送到以该门所在宫室为中心周围8格中任一宫室(如果目标宫室存在的话)。
    

    深谋远虑的Henry当然事先就搞到了所驼门王当年的宫殿招标册,书册上详细记录了每扇传送门所属宫室及类型。而且,虽然宫殿内外相隔,但他自行准备了一种便携式传送门,可将自己传送到殿内任意一间宫室开始寻宝,并在任意一间宫室结束后传送出宫。整座宫殿只许进出一次,且便携门无法进行宫室之间的传送。不过好在宫室内传送门的使用没有次数限制,每间宫室也可以多次出入。

    现在Henry已经打开了便携门,即将选择一间宫室进入。为得到尽多宝藏,他希望安排一条路线,使走过的不同藏宝宫室尽可能多。请你告诉Henry这条路线最多行经不同藏宝宫室的数目。
    输入输出格式
    输入格式:

    输入文件sotomon.in

    第一行给出三个正整数N, R, C。

    以下N行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第xi行第yi列的藏宝宫室,类型为Ti。Ti是一个1~3间的整数,1表示可以传送到第xi行任意一列的“横天门”,2表示可以传送到任意一行第yi列的“纵寰门”,3表示可以传送到周围8格宫室的“自河蟹河蟹门”。

    保证1≤xi≤R,1≤yi≤C,所有的传送门位置互不相同。

    输出格式:

    输出文件sotomon.out只有一个正整数,表示你确定的路线所经过不同藏宝宫室的最大数目。

    输入样例#1:

    10 7 7
    2 2 1
    2 4 2
    1 7 2
    2 7 3
    4 2 2
    4 4 1
    6 7 3
    7 7 1
    7 5 2
    5 2 1

    输出样例#1:

    9

    题解

    和洛谷的缩点模板题简直不要一样。。。。
    首先考虑建边,我暴力建边然后就过了???
    用vector存一下每一行每一列的点
    然后map储存一下点的位置
    对于每一种门,暴力连上边
    恩,解决完了连边
    剩下的很简单啦
    Tarjan缩点
    然后重新连边
    用一个虚拟点作为源点
    跑SPFA最长路就可以啦

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define MAX 110000
    #define MAXL 5000050
    #define INF 1000000000
    inline int read()
    {
    	int x=0,t=1;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return x*t;
    }
    struct Node
    {
    	int x,y;
    };
    inline bool operator <(Node a,Node b)
    {
    	if(a.x!=b.x)
    		return a.x<b.x;
    	else return a.y<b.y;
    }
    struct Line
    {
    	int v,next;
    }e[MAXL];
    struct Line2
    {
    	int v,next,w;
    }ee[MAXL];
    int H[MAX],cnt2=1;
    inline void Add(int u,int v,int w)
    {
    	ee[cnt2]=(Line2){v,H[u],w};
    	H[u]=cnt2++;
    }
    int N,M;
    int h[MAX],cnt=1;
    int w[MAX],dis[MAX],ans;
    int xx[MAX],yy[MAX],tt[MAX];
    inline void Add(int u,int v)
    {
    	e[cnt]=(Line){v,h[u]};
    	h[u]=cnt++;
    }
    int tim,S[MAX],top;
    bool vis[MAX];
    int W[MAX],G[MAX];
    int dfn[MAX],low[MAX],group;
    vector<int> X[MAX],Y[MAX];
    map<Node,int> qt;
    int d[8][2]={1,0,0,1,-1,0,0,-1,1,1,1,-1,-1,1,-1,-1};
    void Tarjan(int u)
    {
    	dfn[u]=low[u]=++tim;
    	vis[u]=true;S[++top]=u;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(!dfn[v])
    		{
    			Tarjan(v);
    			low[u]=min(low[u],low[v]);
    		}
    		else
    			if(vis[v])
    				low[u]=min(low[u],dfn[v]);
    	}
    	if(low[u]==dfn[u])
    	{
    		++group;
    		int v;
    		do
    		{
    			v=S[top--];
    			W[group]++;
    			G[v]=group;
    			vis[v]=false;
    		}while(v!=u);
    	}
    }
    int main()
    {
    	N=read();read();read();
    	for(int i=1;i<=N;++i)
    	{
    		xx[i]=read();yy[i]=read();tt[i]=read();
    		X[xx[i]].push_back(i);Y[yy[i]].push_back(i);
    		qt[(Node){xx[i],yy[i]}]=i;
    	}
    	for(int i=1;i<=N;++i)
    	{
    		if(tt[i]==1)
    		{
    			for(int j=0,l=X[xx[i]].size();j<l;++j)
    				Add(i,X[xx[i]][j]);
    		}
    		else if(tt[i]==2)
    		{
    			for(int j=0,l=Y[yy[i]].size();j<l;++j)
    				Add(i,Y[yy[i]][j]);
    		}
    		else
    		{
    			for(int j=0;j<8;++j)
    			{
    				int xxx=xx[i]+d[j][0];
    				int yyy=yy[i]+d[j][1];
    				Node uuu=(Node){xxx,yyy};
    				if(qt.find(uuu)!=qt.end())
    					Add(i,qt[uuu]);
    			}
    		}
    	}
    	for(int i=1;i<=N;++i)
    		if(!dfn[i])
    			Tarjan(i);
    	for(int u=1;u<=N;++u)
    	{
    		for(int i=h[u];i;i=e[i].next)
    		{
    			int v=e[i].v;
    			if(G[u]!=G[v])
    				Add(G[u],G[v],W[G[v]]);
    		}
    	}
    	for(int i=1;i<=group;++i)Add(0,i,W[i]);
    	queue<int> Q;while(!Q.empty())Q.pop();
    	int ans=0;
    	memset(vis,0,sizeof(vis));
    	Q.push(0);vis[0]=true;
    	while(!Q.empty())
    	{
    		int u=Q.front();Q.pop();
    		for(int i=H[u];i;i=ee[i].next)
    		{
    			int v=ee[i].v,w=ee[i].w;
    			if(dis[v]<dis[u]+w)
    			{
    				dis[v]=dis[u]+w;
    				ans=max(ans,dis[v]);
    				if(!vis[v])
    				{
    					vis[v]=true;
    					Q.push(v);
    				}
    			}
    		}
    		vis[u]=false;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    [python]如何理解uiautomator里面的 instance 及使用场景
    [python]如何理解uiautomator里面的 right,left,up,down 及使用场景
    [python] try......except.....finally
    [python]python官方原版编码规范路径
    [python]pip 版本9.0.1升级到10.0.1故障解决办法
    [python]如何理解uiautomator里面的 child, child_by_text, sibling,及使用场景
    [python]关于在python中模块导入问题追加总结
    [Eclipse]如何往eclipse中导入单个python文件,其它类型代码文件也可以参照该方法
    [Eclipse]在重命令文件名时,提示编码格式有问题导致修改失败,需要设置如下几个默认编码为UTF-8
    [MySQL]在安装windows版MySQL时遇到过如下问题Error Nr.1045和Error.Nr.2003,相应解决办法如下
  • 原文地址:https://www.cnblogs.com/cjyyb/p/7623972.html
Copyright © 2020-2023  润新知