首页 > 代码库 > noi2014魔法森林
noi2014魔法森林
为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士。魔法森林可以被看成一个包含 ?? 个节点 ?? 条边的无向图,节点标号为
1,2,3, ... , ??,边标号为 1,2,3, ... , ??。初始时小 E 同学在 1 号节点,隐士则住在 ?? 号节点。小 E 需要通过这一片魔法森林,才能够拜访到隐士。
魔法森林中居住了一些妖怪。每当有人经过一条边的时候,这条边上的妖怪 就会对其发起攻击。幸运的是,在 1 号节点住着两种守护精灵:A 型守护精灵与 B 型守护精灵。小 E 可以借助它们的力量,达到自己的目的。
只要小 E 带上足够多的守护精灵,妖怪们就不会发起攻击了。具体来说,无 向图中的每一条边 ???? 包含两个权值 ???? 与 ???? 。若身上携带的 A 型守护精灵个数不 少于 ???? ,且 B 型守护精灵个数不少于 ???? ,这条边上的妖怪就不会对通过这条边 的人发起攻击。当且仅当通过这片魔法森林的过程中没有任意一条边的妖怪向 小 E 发起攻击,他才能成功找到隐士。
由于携带守护精灵是一件非常麻烦的事,小 E 想要知道,要能够成功拜访到 隐士,最少需要携带守护精灵的总个数。守护精灵的总个数为 A 型守护精灵的 个数与 B 型守护精灵的个数之和。
题解:
动态加点,跑堆优化迪杰斯特拉;
比SPFA不知道高到哪里去了;
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<cstdlib> #include<ctime> #include<algorithm> #include<queue> using namespace std; #define mid ((l+r)>>1) #define LL long long #define FILE "dealing" #define up(i,j,n) for(LL i=(j);i<=(n);i++) #define pii pair<int,int> int read(){ int x=0,f=1,ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘)x=(x<<1)+(x<<3)+ch-‘0‘,ch=getchar(); return f*x; } const int maxn=300010,inf=100000000,mod=998244353; int n,m; struct bian{int x,y,a,b;}e[maxn]; bool cmp(bian a,bian b){return a.a<b.a;} struct node{int y,next,b,a;}E[maxn]; int linkk[maxn],len=0; void insert(int x,int y,int a,int b){E[++len].y=y;E[len].next=linkk[x];linkk[x]=len;E[len].a=a;E[len].b=b;} int q[maxn],d[maxn],a[maxn],b[maxn],ANS=inf,head,tail,vis[maxn]; priority_queue<pii,vector<pii >,greater<pii > > p; void SPFA(int u,int v,int A){ p.push(make_pair(b[u],u));p.push(make_pair(b[v],v)); while(!p.empty()){ pii d=p.top();p.pop(); if(d.first>b[d.second])continue; int x=d.second; for(int i=linkk[x];i;i=E[i].next){ if(b[E[i].y]>max(b[x],E[i].b)){ b[E[i].y]=max(b[x],E[i].b); p.push(make_pair(b[E[i].y],E[i].y)); } } } if(b[n]+A<ANS)ANS=b[n]+A; } int main(){ //freopen(FILE".in","r",stdin); //freopen(FILE".out","w",stdout); n=read(),m=read(); up(i,1,m)e[i].x=read(),e[i].y=read(),e[i].a=read(),e[i].b=read(); sort(e+1,e+m+1,cmp); memset(b,10,sizeof(b)); b[1]=0;bool flag=0; up(i,1,m){ if(e[i].a>ANS)break; insert(e[i].x,e[i].y,e[i].a,e[i].b); insert(e[i].y,e[i].x,e[i].a,e[i].b); if((e[i].x==1||e[i].y==1)^(e[i].x==1&&e[i].y==1))flag=1; if(flag)SPFA(e[i].x,e[i].y,e[i].a); } printf("%d\n",ANS==inf?-1:ANS); //cout<<clock()<<endl; return 0; }
noi2014魔法森林
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。