标签:间接 include signed front input unsigned har max first
由于做过最优贸易,所以对于点到达终点的条件可以很容易转换,建立反图,从t跑。
考虑所有路径上的点满足出边的点都能到终点的条件,可以在dfs时记录到达该节点的次数,
该次数等同于这个点出边的点可以到t的个数。
最后再用满足条件的点建出正向的图,跑最短路即可。
于是愉快的spfa和只是大的大数据。
#include<bits/stdc++.h> using namespace std; const int maxn=100005; int n,m,s,t; vector<pair<int,int> >e[maxn],a[maxn]; int chu[maxn],cnt[maxn]; template<class T>inline void read(T &x){ x=0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} } void dfs(int u){ //printf("%d ",u); for(unsigned int i=0;i<a[u].size();i++){ int v=a[u][i].first; cnt[v]++; if(cnt[v]==1) dfs(v); } } queue<int> q; bool vis[maxn]; int dis[maxn]; void spfa(){ for(int i=1;i<=n;i++) dis[i]=0x7ffffff; q.push(s); vis[s]=true;dis[s]=0; while(!q.empty()){ int x=q.front(); q.pop(); vis[x]=false; for(unsigned int i=0;i<e[x].size();i++){ int y=e[x][i].first; if(dis[y]>dis[x]+e[x][i].second){ dis[y]=dis[x]+e[x][i].second; if(!vis[y]) {vis[y]=true;q.push(y);} } } } } int main(){ freopen("path.in","r",stdin); freopen("path.out","w",stdout); read(n);read(m); for(int i=1;i<=m;i++){ int x,y,z; read(x);read(y);read(z); if(x==y) continue; chu[x]++; a[y].push_back(make_pair(x,z)); } read(s);read(t); cnt[t]=1; dfs(t); //for(int i=1;i<=n;i++) printf("%d %d\n",cnt[i],chu[i]); if(!cnt[s]) {printf("-1");return 0;} cnt[t]=chu[t]; for(int i=1;i<=n;i++) if(cnt[i]==chu[i]){ for(unsigned int j=0;j<a[i].size();j++){ int x=a[i][j].first,y=a[i][j].second; if(chu[x]==cnt[x]){ e[x].push_back(make_pair(i,y)); //printf("%d %d %d\n",i,x,y); } } } spfa(); if(dis[t]==0x7ffffff) printf("-1"); else printf("%d",dis[t]); } /*6 7 2 1 3 1 4 1 4 1 5 1 4 1 6 1 4 */
关于spfa,他死了
都9102年了,还有人卡spfa
只有用堆优化的dijkstra
#include<bits/stdc++.h> using namespace std; const int maxn=1000005; #define ll long long int n,m,s,t; vector<pair<int,ll> >e[maxn],a[maxn]; int chu[maxn],cnt[maxn]; template<class T>inline void read(T &x){ x=0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} } void dfs(int u){ //printf("%d ",u); for(unsigned int i=0;i<a[u].size();i++){ int v=a[u][i].first; cnt[v]++; if(cnt[v]==1) dfs(v); } } priority_queue < pair < ll,int >,vector < pair < ll,int > >,greater < pair < ll ,int > > > q; bool vis[maxn]; ll dis[maxn]; void dijkstra(){ for(int i=1;i<=n;i++) dis[i]=0x7fffffff; dis[s]=0; q.push(make_pair(dis[s],s)); while(!q.empty()){ int x=q.top().second; q.pop(); if(vis[x]) continue; vis[x]=true; for(unsigned int i=0;i<e[x].size();i++){ int y=e[x][i].first; if(vis[y]) continue; if(dis[y]>dis[x]+e[x][i].second){ dis[y]=dis[x]+e[x][i].second; q.push(make_pair(dis[y],y)); } } } } int main(){ freopen("path.in","r",stdin); freopen("path.out","w",stdout); read(n);read(m); for(int i=1;i<=m;i++){ int x,y; ll z; read(x);read(y);read(z); if(x==y) continue; chu[x]++; a[y].push_back(make_pair(x,z)); } read(s);read(t); cnt[t]=1; dfs(t); //for(int i=1;i<=n;i++) printf("%d %d\n",cnt[i],chu[i]); if(!cnt[s]) {printf("-1");return 0;} cnt[t]=chu[t]; for(int i=1;i<=n;i++) if(cnt[i]==chu[i]){ for(unsigned int j=0;j<a[i].size();j++){ int x=a[i][j].first,y=a[i][j].second; if(chu[x]==cnt[x]){ e[x].push_back(make_pair(i,y)); //printf("%d %d %d\n",i,x,y); } } } dijkstra(); if(dis[t]==0x7fffffff) printf("-1"); else printf("%lld",dis[t]); } /*6 7 1 2 1 1 3 1 3 4 1 2 4 1 3 5 1 5 4 1 5 6 1 1 4 */
标签:间接 include signed front input unsigned har max first
原文地址:https://www.cnblogs.com/sto324/p/11181659.html