bzoj2330: [SCOI2011]糖果
差分约束,dag最长路。
坑点在于有一个100000 长的链,虚拟节点倒序加就a了。
用queue是太懒,tyvj上过不了。
#include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int maxn = 100000 + 10; const int maxm = 400000 + 10; int n,k; int g[maxn],v[maxm],next[maxm],d[maxm],eid=0; queue<int> q; bool inque[maxn]; int t[maxn],f[maxn]; void addedge(int a,int b,int D) { v[eid]=b; d[eid]=D; next[eid]=g[a]; g[a]=eid++; } void build() { scanf("%d%d",&n,&k); memset(g,-1,sizeof(g)); for(int i=1,u,v,x;i<=k;i++) { scanf("%d%d%d",&x,&u,&v); switch(x) { case 1: addedge(u,v,0); addedge(v,u,0); break; case 4: swap(u,v); case 2: addedge(u,v,1); break; case 3: swap(u,v); case 5: addedge(u,v,0); break; } } for(int i=n;i>=1;i--) addedge(0,i,1); //printf("sda"); } long long SPFA() { memset(f,0xef,sizeof(f)); q.push(0); f[0]=0; inque[0]=1; while(!q.empty()) { int u = q.front(); q.pop(); inque[u]=0; for(int i=g[u];~i;i=next[i]) if(f[v[i]] < d[i]+f[u]) { f[v[i]] = d[i]+f[u]; t[v[i]] = t[u]+1; if(t[v[i]]>=n+1) return -1; if(!inque[v[i]]) q.push(v[i]),inque[v[i]]=1; } } long long res=0; for(int i=1;i<=n;i++) res+=f[i]; return res; } void solve() { printf("%lld\n",SPFA()); } int main() { build(); solve(); return 0; }