题解 P1685 【游览】
我真是菜鸡,题读了半天才懂,代码敲出来调了1个多小时,结果是输入打错了。
My vegetable has exploded……
咳咳
思路
这题我真的读了很久,一直没搞懂是啥意思……
我先来解释一下题意,
就是有一个DAG,有一个起点s和一个终点t。
这个人要从起点s走完所有可以到达终点t的方案,求出他所走过的每一条方案的边权和
理解了题意,可以想想怎么做了。
首先,他给出的图是一个DAG。
其次他还让我们求所有方案的和。
假设
很明显,我们可以用拓扑排序+递推的思想,根据起点
假设,点
所以,如果当前点为
相类似的,当前点
好了,有点绕,看代码
code
#include<cstdio>
#include<queue>
using namespace std;
const int mod=10000;
const int maxn1=1e4+7;
const int maxn2=5e4+7;
struct edge{int to,next,w;}map[maxn2];
int n,m,s,t,t0,in[maxn1],count[maxn1],dis[maxn1];
int cnt,head[maxn1];
queue<int>q;
int read(){
char ch=getchar();int f=1,r=0;
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){r=r*10+ch-'0';ch=getchar();}
return f*r;
}
void add(int x,int y,int w){
map[++cnt].to=y;
map[cnt].w=w;
map[cnt].next=head[x];
head[x]=cnt;
in[y]++;
return ;
}
void toposort(){
q.push(s);
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=head[x];i;i=map[i].next){
int y=map[i].to,w=map[i].w;
(dis[y]+=dis[x]+count[x]*w)%=mod;
(count[y]+=count[x])%=mod;
if(!(--in[y])) q.push(y);
}
}
return ;
}
int main(){
n=read(),m=read(),s=read(),t=read(),t0=read();
//for(int i=1;i<=m;i++) add(read(),read(),read());//调了一个小时
int x,y,w;
for(int i=1;i<=m;++i) x=read(),y=read(),w=read(),add(x,y,w);
count[s]=1;
toposort();
printf("%d",(dis[t]+(count[t]-1)*t0)%mod);//当他最后一次游览时,就不需要回去了,所以-1。
return 0;
}