复习判正环两种方法:
1、spfa入队总次数达2*(N+M)则认为存在正环
2、所有点d数组初值为0+spfa_dfs
参考 《spfa的优化及应用》——姜碧野
之前做过的另一题http://blog.youkuaiyun.com/chm517/article/details/9389837
#include<stack>
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
#include<algorithm>
#include<queue>
#define sqr(x) (x)*(x)
#define f1 first
#define f2 second
#define pb push_back
#define fr(i,x,y) for(int i=x;i<=y;++i)
#define ms(x,y) memset(x,y,sizeof(x))
#define sqr(x) (x)*(x)
typedef long long ll;
const ll inf=(1ll)<<50;
#define N 100005
#define M 1000005
const int maxans=1000000000;
using namespace std;
struct edge{
int to,next;
ll w;
}e[M];
struct rr{
int op;
int id;
bool operator<(const rr&oth)const{
return id<oth.id;
}
}b[N];
struct line{
int op;
ll tim;
int num;
}a[N];
deque<int> q;
int head[N],vis[N],typ[N],cen[N],id[N],num[N],fun[N];
ll d[N];
int n,o,m,nown,ce,sz,all,idd;
ll ans3310;
void add(int x,int y,ll z)
{
if (y>nown) return;
all+=z;
e[o].to=y;
e[o].next=head[x];
e[o].w=z;
head[x]=o++;
}
inline bool maximize(ll& a,ll b)
{
if (b<=a) return 0;
a=b;
return 1;
}
bool spfa(int now)
{ vis[now]=1;
for (int k=head[now];k!=-1;k=e[k].next)
if (d[e[k].to]<d[now]+e[k].w)
{ d[e[k].to]=d[now]+e[k].w;
if (!vis[e[k].to])
if (spfa(e[k].to)) return 1;else;
else return 1;
}
vis[now]=0;
return 0;
}
bool spfa_getans(int n,int initial)
{
fr(i,1,n){d[i]=0;vis[i]=0;}
if (spfa(1)) return 0;//RIGHT!
//WA!in this case{die,……} fr(i,1,n)if (spfa(i)) return 0;
fr(i,1,n){d[i]=0;vis[i]=0;num[i]=0;}
d[1]=initial;
while (!q.empty()) q.pop_front();
q.push_front(1);vis[1]=1; num[1]++;
int j,v,RD=0,RDM=(o+n)*2+10;
while (!q.empty())
{
j=q.front();q.pop_front();
vis[j]=0;
if (typ[j]){ans3310=max(ans3310,d[j]);continue;}
for (int k=head[j];k!=-1;k=e[k].next)
{ v=e[k].to;
if (maximize(d[v],d[j]+e[k].w))
{ if (d[v]>all) return 0;
if (!vis[v]) {num[v]++;
if (!q.empty())
if(d[v]<q.front())q.push_front(v);else q.push_back(v);
else q.push_back(v);
RD++;
//if (RD>RDM) return 0;
if (num[v]>n) return 0;
}
}
}
}
return 1;
}
char s[100];
stack<ll> st2;
int aa[N],bb[N],cc[N];
void ret()
{ fun[n+1]=1;//fun[n+1]=int(log(n+1)/log(10)+1e-9)+1;
puts("infinity");
}
void ggg(int l,int r)
{
fr(j,l,r-1)
{
if (a[j].op==1) add(id[j],id[a[j].num],fun[a[j].num]),add(id[j],id[j+1],fun[j+1]);
if (a[j].op==2) add(id[j],id[a[j].num],fun[a[j].num]);
if (a[j].op==3) add(id[j],id[j+1],fun[j+1]);
if (a[j].op==5) typ[id[j]]=1;
}
int j=r;if (a[j].op==5) typ[id[j]]=1;
}
bool doit()
{ n=0; m=0; ans3310=0;
int re=0,len,yes,dieflag=0;
char *ss,*s2;
while (gets(s))
{
len=strlen(s);
yes=0;
fr(j,0,len-1)
{if (s[j]=='i'||s[j]=='I'){a[++n].op=1;yes=1;ss=s+j+4;break;}
if (s[j]=='j'||s[j]=='J'){a[++n].op=2;yes=1;ss=s+j+4;break;}
if (s[j]=='p'||s[j]=='P'){a[++n].op=3;yes=1;ss=s+j+4;break;}
if (s[j]=='l'||s[j]=='L'){a[++n].op=4;yes=1;ss=s+j+4;break;}
if (s[j]=='d'||s[j]=='D'){dieflag=1;a[++n].op=5;yes=1;ss=s+j+3;break;}
}
if (!yes){re=1; break;}
while (*ss==' ') ss++;
s2=ss;
int tmp=0;ll x=0;
while (*s2>='0'&&*s2<='9'){tmp++;if (tmp<10)x=x*10+(*s2)-'0';s2++;}
if (a[n].op==1||a[n].op==2||a[n].op==4)
{ if (tmp<6||(tmp==6&&x==1000000))
a[n].num=int(x);else puts("~~~~~~~~~E1");
if (a[n].op==4)
{
b[++m].op=0; b[m].id=int(x);
b[++m].op=1; b[m].id=n;
}
}
ss=s2; while (*ss==' ') ss++;
s2=ss;
tmp=0;x=0;
while (*s2>='0'&&*s2<='9'){tmp++;if (tmp<10)x=x*10+(*s2)-'0';s2++;}
if (a[n].op==4)
{ if (tmp<10)
a[n].tim=x;else puts("~~~~~~~~~E2");
}
}
if (!dieflag) {ret();return re;}
b[++m].op=0; b[m].id=0;
b[++m].op=1; b[m].id=n+1;
fun[n+1]=0;
a[0].op=3; a[n+1].op=4;a[n+1].tim=1000000000;
sort(b+1,b+m+1);
while (!st2.empty()) st2.pop();
int last=0,lastop=-1,l,r;
ce=0,sz=0;
ms(cen,255);
//------------------------------------
fr(i,1,m)
{
if (b[i].op==0)
{ if (lastop==1) last++;
if (last<b[i].id) { aa[sz]=(last);
bb[sz]=(b[i].id-1);
cc[sz]=(ce);
sz++;
}
ce++;
last=b[i].id;
lastop=b[i].op;
continue;
}
if (lastop==1)
{
nown=0;all=0;
int j_min=sz;
for (int j=sz-1;j>=0;j--)if (ce==cc[j])j_min=j;else break;
fr(j,j_min,sz-1) fr(k,aa[j],bb[j]) id[k]=++nown;
if (last+1<=b[i].id) fr(k,last+1,b[i].id) id[k]=++nown;
o=0;fr(j,1,nown)head[j]=-1,typ[j]=0;
l=last+1,r=b[i].id;ggg(l,r);
int mm=last+1;
ll mmm=st2.top();st2.pop();
while (cc[sz-1]==ce)
{
l=aa[sz-1];r=bb[sz-1];
ggg(l,r);
sz--;
add(id[r],id[mm],mmm+fun[mm]);
mm=l;
}
r=b[i].id;
all+=fun[l];if (!spfa_getans(nown,fun[l])){ret();;return re;}
ll tmp=d[nown]*a[r].tim;
if (tmp>maxans){ret();;return re;}
st2.push(tmp);last=b[i].id;lastop=b[i].op;
ce--;
continue;
}
ce--;
l=last,r=b[i].id;
nown=0; all=0;
fr(j,l,r)id[j]=++nown;
o=0;fr(j,1,nown)head[j]=-1,typ[j]=0;
ggg(l,r);
all+=fun[l]; if (!spfa_getans(nown,fun[l])){ret();;return re;}
ll tmp=d[nown]*a[r].tim;
if (tmp>maxans){ret();;return re;}
st2.push(tmp);last=b[i].id;lastop=b[i].op;
}
if (ans3310>maxans){ret();;return re;}
printf("%lld\n",ans3310);
fun[n+1]=1;//fun[n+1]=int(log(n+1)/log(10)+1e-9)+1;
return re;
}
int main()
{
fun[0]=0;
fr(i,1,100000) fun[i]=1;//fun[i]=int(log(i)/log(10)+1e-9)+1;
idd=0;
while (doit());
}