博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P3119 [USACO15JAN]草鉴定Grass Cownoisseur
阅读量:5912 次
发布时间:2019-06-19

本文共 2488 字,大约阅读时间需要 8 分钟。


如果不可以反向走的话。这个题的难度就如此的变态。

先不考虑逆向走。

然后我们先分析一波这个图的。可以讲图中的点分为三类。

~标号为1的点

~能到达1的点

~能从1点到达的点

很显然,若只有能到达1的点,或者只有从1可以到达的点。这个图就无法从1出发,然后再回到1。

然后上面两部分点肯定不能所载一起。但是如果我们逆向走的话。就相当从1可以到达的点中,引出了一条连向可以到达1的点的一条边。就构成了一个环。

所以我们就可以枚举一下满足连接上这两部分点的边,然后取一个最优值

具体代码实现的话就是tarjan+spfa(两次,求出两部分的点和)

#include
#include
#include
#include
#include
using namespace std;const int maxn=101000;struct node{ int from; int point; int nxt;};node L1[maxn<<1],L2[maxn<<1],L3[maxn<<1];int H1[maxn],H2[maxn],H3[maxn],T1,T2,T3;int belong[maxn],num[maxn],cnt;int Map[maxn];int dfn[maxn],low[maxn],t;int stack[maxn],top;int insta[maxn];vector
Contain[maxn];bool inque[maxn];int Dis1[maxn],Dis2[maxn],ans;void add1(int a,int b){ L1[++T1].point=b; L1[T1].nxt=H1[a]; H1[a]=T1;}void add2(int a,int b){ L2[++T2].point=b; L2[T2].nxt=H2[a]; H2[a]=T2;}void add3(int a,int b){ L3[++T3].from=a; L3[T3].point=b; L3[T3].nxt=H3[a]; H3[a]=T3;}void tarjan(int now){ dfn[now]=low[now]=++t; stack[++top]=now; insta[now]=true; for(int i=H1[now];i;i=L1[i].nxt) { int nxt=L1[i].point; if(!dfn[nxt]) { tarjan(nxt); low[now]=min(low[now],low[nxt]); } else if(insta[nxt]&&dfn[nxt]
q; q.push(belong[1]); inque[belong[1]]=true; Dis1[belong[1]]=-num[belong[1]];//存负,跑最短路 while(!q.empty()) { int pas=q.front();q.pop(); inque[pas]=false; for(int i=H2[pas];i;i=L2[i].nxt) if(Dis1[L2[i].point]>Dis1[pas]-num[L2[i].point]) { Dis1[L2[i].point]=Dis1[pas]-num[L2[i].point]; if(!inque[L2[i].point]); { inque[L2[i].point]=true; q.push((L2[i].point)); } } }}void Spfa2()//反图上跑{ queue
q; q.push(belong[1]);inque[belong[1]]=true; Dis2[belong[1]]=-num[belong[1]]; while(!q.empty()) { int pas=q.front();q.pop(); inque[pas]=false; for(int i=H3[pas];i;i=L3[i].nxt) if(Dis2[L3[i].point]>Dis2[pas]-num[L3[i].point]) { Dis2[L3[i].point]=Dis2[pas]-num[L3[i].point]; if(!inque[L3[i].point]) { inque[L3[i].point]=true; q.push(L3[i].point); } } }}void Star(){ for(int i=1;i<=cnt;i++) for(int j=H3[i];j;j=L3[j].nxt) if(Dis1[L3[j].from]<0&&Dis2[L3[j].point]<0)//枚举 ans=min(ans,Dis1[L3[j].from]+Dis2[L3[j].point]+num[belong[1]]);}int main(){ int n,m; scanf("%d%d",&n,&m); int a,b; for(int i=1;i<=m;i++) { scanf("%d%d",&a,&b); add1(a,b);//存图 } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);//tarjan缩点 for(int i=1;i<=cnt;i++) build(i);//建出缩完点后的图 Spfa1();//求出从1开始可以到达的点数和 Spfa2();//求出可以到达1的点数和 Star();//瞎 star star 枚举 printf("%d",-ans);}

转载于:https://www.cnblogs.com/Lance1ot/p/9255803.html

你可能感兴趣的文章
C#抽象类与接口的区别【转】
查看>>
sublime打开文本时会记忆上次关闭时鼠标停留的位置
查看>>
分布式缓存
查看>>
Java Log4j 配置文件
查看>>
django admin后台的简单使用
查看>>
R语言数据可视化2—ggplot2各种维度的业务量统计根据类型统计不同月份的业务量...
查看>>
Blue Moon响应式后台管理模板
查看>>
海量数据库的查询优化及分页算法方案(五)
查看>>
UVA11468 Substring
查看>>
linux 下压缩大批量文件
查看>>
CSS设计模式
查看>>
常见问题解决
查看>>
java容器类1:Collection,List,ArrayList,LinkedList深入解读
查看>>
mysql 数据库修改名字
查看>>
Anagram
查看>>
BIT软件需求工程与UML建模课程第三周工作总结
查看>>
hdu 1330
查看>>
Android C2DM学习 - 云端推送
查看>>
微信开发https服务搭建
查看>>
Error No matching provisioning profiles found
查看>>