题解 P1073 【最优贸易】
不带任何高级技巧的搜索+乱搞哈希
适合蒟蒻阅读
First:
我不会链式前向星,但是邻接矩阵肯定会爆,所以用了很神奇的结构体存图
struct point{
int val;
int tox;//点的出度
int to[500];//所连接的点数组
}q[100000];
只存了最多500个点,怕爆空间,可以水过。
Second:
搜索的时候用一个sta变量表示阶段。
通过阅读可得,贸易可以分为三个阶段:
买珠宝、卖珠宝、去终点
由于三个阶段是顺序做的事情,所以可以分别搜索
最后关于判重:乱搞哈希
我搜索时用到的三个变量:现在所在的地点now,拥有的钱money,以及现处阶段sta。于是就乱搞了这个判重语句:
int hash(int a,int b,int c)
{
return (a*133%MOD+b*97%MOD+c*17%MOD)%MOD;
}//哈希函数
void dfs(int now,int money,int sta)
{
int ha=hash(now,money,sta);
if(HASH[ha]) return ;
HASH[ha]=true;
......
}
完整AC程序
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct point{
int val;
int tox;
int to[500];
}q[100000];
int i,n,m,ans;
int MOD=9999990;
bool HASH[9999990];//哈希判重
void add(int x,int y)
{
q[x].tox++;q[x].to[q[x].tox]=y;
}
int hash(int a,int b,int c)
{
return (a*133%MOD+b*97%MOD+c*17%MOD)%MOD;
}
void dfs(int now,int money,int sta)
{
int j,k;
int ha=hash(now,money,sta);
if(HASH[ha]) return ;
HASH[ha]=true;
if(now==n&&sta==3)
{
if(money>ans) ans=money;
return ;
}//到达终点
if(sta==1)
{
for(j=1;j<=q[now].tox;j++)
{
//在这里买
dfs(q[now].to[j],q[now].val,2);
//不在这里买
dfs(q[now].to[j],money,1);
}
}
else if(sta==2) //卖
{
for(j=1;j<=q[now].tox;j++)
{
//在这里卖
if(q[now].val-money>ans)
dfs(q[now].to[j],q[now].val-money,3);
//不卖
dfs(q[now].to[j],money,2);
}
}
else
{
for(j=1;j<=q[now].tox;j++)
dfs(q[now].to[j],money,3);
}//去终点
return ;
}
int main()
{
cin>>n>>m;
for(i=1;i<=n;i++)
cin>>q[i].val;
for(i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
add(x,y);
if(z==2) add(y,x);
}
dfs(1,0,1);
cout<<ans;
}