题解 P1993 【小K的农场】

ouuan

2018-09-05 13:44:39

Solution

竟然全是dfs_SPFA(当然还有一个scc的...),~~你们不知道dfs_SPFA已经死了吗~~ 还是slfNB! 差分约束其它题解已经讲的很清楚了,slf就是在spfa入队时如果待入队元素的dis比队首小就从队首入队,否则从队尾入队,可以用deque实现。 至于连通性问题,全部从0连一条零权边确实很简洁,但实测跑的慢一些..我是直接用vis存每个节点是否跑过spfa,没跑过的就跑一遍。 ``` #include <iostream> #include <cstdio> #include <deque> #include <cstring> using namespace std; void add(int u,int v,int w); int head[10010],nxt[20010],to[20010],edge[20010],cnt; int n,m,dis[10010],tot[10010]; bool inq[10010],vis[10010]; deque<int> q; int main() { int i,j,type,c,u,v; cin>>n>>m; for (i=1;i<=n;++i) { dis[i]=100000000; } for (i=0;i<m;++i) { cin>>type>>u>>v; if (type==1) { cin>>c; add(u,v,-c); } else if (type==2) { cin>>c; add(v,u,c); } else { add(u,v,0); add(v,u,0); } } for (j=1;j<=n;++j) { if (!vis[j]) { memset(tot,0,sizeof(tot)); dis[j]=0; tot[j]=1; q.push_front(j); while (!q.empty()) { u=q.front(); q.pop_front(); inq[u]=false; vis[u]=true; for (i=head[u];i;i=nxt[i]) { v=to[i]; c=edge[i]; if (dis[v]>dis[u]+c) { dis[v]=dis[u]+c; if (!inq[v]) { if (++tot[v]>n) { cout<<"No"; return 0; } inq[v]=true; if (q.empty()||dis[v]<dis[q.front()]) //slf优化 { q.push_front(v); } else { q.push_back(v); } } } } } } } cout<<"Yes"; return 0; } void add(int u,int v,int w) { nxt[++cnt]=head[u]; head[u]=cnt; to[cnt]=v; edge[cnt]=w; } ```