描述

    在唐山一中,吃饭是一件很令人头疼的事情,因为你不可能每次都站在队伍前面买饭,所以,你最需要做的一件事就是——跑饭。而跑饭的道路是无比艰难的,因为路是单向的(你要非说成是双向的我也没法,前提是你可以逆着2000+个狂热的跑饭群众而行),所以要合理选择路线。并且,在抵达你的目的地——板面馆之前,你需要先买一些干粮,比如烧饼之类的。现在给你每个干食商店的位置和干食喜爱度,请你设计一个跑饭方案使得在到达板面馆之前能得到尽可能多的干食喜爱度。

输入格式

    第一行包含两个整数N、M。N表示食品商店的个数,M表示道路条数。接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道 路的起点和终点的食品商店编号。接下来N行,每行一个整数,按顺序表示每个食品商店处的干食喜爱度。接下来一行包含两个整数S、P,S表示学校的编号,也就是出发地点。P表示板面馆数目。接下来的一行中有P个整数,表示P个卖板面的食品商店的编号。

输出格式

输出一个整数,表示到达板面馆之前能得到的最多的干食喜爱度。

测试样例1

输入

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

16 


1 4 
4 3 5 6

输出

47

备注

40%的数据n,m<=300   100%的数据n,m<=3000 

思路:

1、分析路可以重复走,想到强连通分量,如果强连通分量里面有一个点被访问,那么整个强连通分量都要被访问,否则答案偏小,于是先tarjan再缩点

2、缩点之后,整个图由一个有向有环图变为一个有向无环图,于是spfa处理,然后就AC了(bzoj上的好像能卡掉,WYW用tarjan写信息传递好像被卡了)

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
#include<stack>
#define maxn 3005
#define maxint ~0U>>1
using namespace std;
stack<int> sta;
vector<int> comp[maxn];
int incomp[maxn],instack[maxn],dfn[maxn],low[maxn];
int index,cnum;
int n,m,q,d[maxn],rice[maxn],noodle[maxn],v[maxn],s,p,ans;
vector<int> g[maxn],nowg[maxn];
int nowrice[maxn],nownoodle[maxn],nows;
void input(){
cin>>n>>m;
int u,v;
for(int i = ;i <= m;i++){
scanf("%d%d",&u,&v);
g[u].push_back(v); }
for(int i = ;i <= n;i++){
scanf("%d",&rice[i]);
}
cin>>s>>p;
int nnow;
for(int i = ;i <= p;i++){
scanf("%d",&nnow);
noodle[nnow] = ;
}
}
void tarjan(int u){
instack[u] = ;
dfn[u] = low[u] = ++index;
sta.push(u);
for(int i = ;i < g[u].size();i++){
int j = g[u][i];
if(!dfn[j]){
tarjan(j);
low[u] = min(low[u],low[j]);
}else if(instack[j] == ){
low[u] = min(low[u],dfn[j]);
}
}
if(dfn[u] == low[u]){
++cnum;
while(!sta.empty()){
int t = sta.top();
sta.pop();
instack[t] = ;
incomp[t] = cnum;
comp[cnum].push_back(t);
if(t == u){
break;
}
}
}
}
void work(){
for(int i = ;i <= n;i++){
if(!dfn[i]) tarjan(i);
}
int u,v,newu,newv;
for(int i = ;i <= n;i++){
u = i;
newu = incomp[u];
nowrice[newu] += rice[u];
if(noodle[u]) nownoodle[newu] = ;
if(u == s) nows = newu;
for(int j = ;j < g[u].size();j++){
v = g[u][j];
newv = incomp[v];
if(newu == newv) continue;
nowg[newu].push_back(newv);
}
}
}
void spfa(){
queue<int> q;
d[nows] = nowrice[nows];
v[nows] = ;
q.push(nows);
int xx,dd,to,wei;
while(!q.empty()){
xx = q.front();
dd = d[xx];
q.pop();
v[xx] = ;
if(nownoodle[xx]) ans = max(ans,dd);
for(int i = ;i < nowg[xx].size();i++){
to = nowg[xx][i];
wei = nowrice[to];
if(dd + wei > d[to]){
d[to] = dd + wei;
if(!v[to]){
v[to] = ;
q.push(to);
}
}
}
}
cout<<ans;
}
int main(){
input();
work();
spfa();
return ;
}

最新文章

  1. 【搬砖】【Python数据分析】Pycharm中plot绘图不能显示出来
  2. Cobar分布式数据库的应用与实践
  3. C语言对文件的相关命令
  4. Bash常用快捷键
  5. Unix/Linux环境C编程入门教程(30) 字符串操作那些事儿
  6. MVC UnitOfWork EntityFramework架构
  7. [解读REST] 4.基于网络应用的架构风格
  8. FreeSql.Repository 通用仓储层功能
  9. Spring Boot系列(一) Spring Boot准备知识
  10. 【HTML】行内-块级-行块级
  11. 灵活运用 SQL SERVER FOR XML PATH 转
  12. Sharepoint2013 Report Service初探
  13. hadoop集群配置SSH免登陆
  14. kubectl error: The connection to the server localhost:8080 was refused
  15. ajax请求session失效重定向到登录页面
  16. async之诗句慢慢出现
  17. java高cpu占用和高内存占用问题排查 (转)
  18. 题解 P1682 【过家家】
  19. ASP.NET与.NET区别
  20. 常用数字信号的产生(C实现)-ARMA模型数据生成

热门文章

  1. TestNG设置用例循环执行
  2. 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 Overlapping Rectangles
  3. 2017杭电多校第七场1011Kolakoski
  4. Oracle随机选择一条记录SQL
  5. Android 性能优化(1)性能工具之「 lint 」 :Improving Your Code with lint:优化代码
  6. 为 C# 代码生成 API 文档(自译)
  7. UML中类之间的关系
  8. oracle in表达式参数支持最大上限1000个
  9. Android学习笔记(四) JAVA基础知识回顾
  10. Angular——依赖注入