[A through study notes] Negative ring

Negative loop problem can usually use the SPFA dfs and bfs achieve to complete. Note that the SPFA bfs implementation complexity may soared to O (n ^ 3) and therefore not suitable for use, so we usually dfs achieve. (Though feel the complexity of this stuff is not particularly stable?)
Need to pay attention to two issues

  • Shortest time required to run a negative ring or the longest road meaning of the questions to be decided
  • No need to set the initial state of dis is infinity, otherwise it may fall T

    10082. "3.3 cases through a 1" Word Rings

    Simple construction drawing attention here to run the longest road
#include <bits/stdc++.h>
using namespace std;

vector <pair<int,double> > g[1000005];

namespace SPFA {
    int m,ins[1000005],vis[1000005],fg=0,t1,t2,t3;
    double dis[1000005];
    vector <pair<int,double> > g[1000005];
    void dfs(int p){
        ins[p]=1; vis[p]=1;
        for(int i=0;i<g[p].size()&&!fg;i++)
            if(dis[g[p][i].first]<dis[p]+g[p][i].second){
                dis[g[p][i].first]=dis[p]+g[p][i].second;
                if(ins[g[p][i].first]==0)
                    dfs(g[p][i].first);
                else {fg=1; return;}}
        ins[p]=0;
    }
    bool solve() {
        int n=1000; fg=0;
        memset(ins,0,sizeof ins);
        memset(vis,0,sizeof vis);
        for(int i=1;i<=n;i++) dis[i]=0;
        for(int i=1;i<=n;i++) {
            if(vis[i]==0)  {
                dfs(i);
            }
            if(fg) return true;
        }
        return false;
    }
}

int T,n;

inline int calc(char x,char y) {
    return (x-'a')*30+(y-'a')+1;
}

int main() {
    while(cin>>n && n) {
        string str;
        for(int i=1;i<=1000;i++)
            g[i].clear();
        for(int i=1;i<=n;i++) {
            cin>>str;
            if(str.length()>1) {
                g[calc(str[0],str[1])].push_back(make_pair(calc(str[str.length()-2],str[str.length()-1]),str.length()));
            }
        }
        double L=0,R=1e+5;
        while(R-L>1e-6) {
            double M=(L+R)/2;
            for(int i=1;i<=1000;i++)
                SPFA::g[i].clear();
            for(int i=1;i<=1000;i++)
                for(int j=0;j<g[i].size();j++)
                    SPFA::g[i].push_back(make_pair(g[i][j].first,g[i][j].second-M)); 
            if(SPFA::solve()) L=M;
            else R=M;
        }
        if(L==0) cout<<"No solution"<<endl;
        else cout<<L<<endl;
    }
} 

10083. "3.3 cases 2 through a" path amphiregulin

This question and did not see anything to have a negative ring, layered graph shortest path to

#include <bits/stdc++.h>
using namespace std;

const int N=1100005;
vector <pair<int,int> > g[N];
int d[N],v[N],n,m,s,e,p,r,c,t;
void make(int t1,int t2,int t3) {
    g[t1].push_back(make_pair(t2,t3));
}
void solve(int v0) {
    queue<int>q;
    d[v0]=0; v[v0]=1;
    q.push(v0);
    while(q.size()) {
        int p=q.front();
        q.pop();
        v[p]=0;
        for(int i=0;i<g[p].size();i++) {
            int x=g[p][i].first,y=g[p][i].second;
            if(d[x]>d[p]+y) {
                d[x]=d[p]+y;
                if(!v[x]) q.push(x), v[x]=1;
            }
        }
    }
}
inline int calc(int nd,int cs) {
    return nd*10200+cs+1;
}
int main() {
    ios::sync_with_stdio(false);
    cin>>n>>m>>s>>e;
    for(int i=1;i<=m;i++) {
        cin>>p>>r>>c>>t;
        for(int j=0;j<=10000;j++) {
            make(calc(p,j),calc(r,j+c),t),
            make(calc(r,j),calc(p,j+c),t);
        }
    }
    int cnt=0;
    memset(d,0x3f,sizeof d);
    solve(calc(s,0));
    int mx=0x3f3f3f3f; 
    for(int i=0;i<=10000;i++)
        cnt+=(d[calc(e,i)]<mx?1:0),
        mx=min(mx,d[calc(e,i)]);
    cout<<cnt<<endl;
    return 0; 
}

10084. "one through 3.3 Exercise 1" minimum circle

Then began a mad infinity dis set more than T

#include <bits/stdc++.h>
using namespace std;

const int N=10005;
int ins[N],vis[N],n,m,flag;
double dis[N],M;
vector <pair<int,double> > g[N];

void dfs(int p) {
    ins[p]=vis[p]=1;
    for(int i=0;i<g[p].size()&&!flag;i++) {
        int q=g[p][i].first;
        if(dis[q]>dis[p]+g[p][i].second-M) {
            dis[q]=dis[p]+g[p][i].second-M;
            if(ins[q]) {
                flag=1;
                return;
            }
            dfs(q);
        }
        if(flag) return;
    }
    ins[p]=0;
}

int main() {
    ios::sync_with_stdio(false);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++) {
        int t1,t2;double t3;
        scanf("%d%d%lf",&t1,&t2,&t3);
        g[t1].push_back(make_pair(t2,t3));
    }
    double L=-1e+7,R=1e+7;
    while(R-L>1e-9) {
        M=(L+R)/2;
        memset(vis,0,sizeof vis);
        memset(ins,0,sizeof ins);
        memset(dis,0,sizeof dis);
        flag=0;
        for(int i=1;i<=n;i++) {
            if(vis[i]==0) {
                dfs(i);
            }
            if(flag) break;
        }
        if(flag) R=M;
        else L=M;
    }
    cout<<setiosflags(ios::fixed)<<setprecision(8)<<L+1e-9<<endl;
}

10085. "one through 3.3 Exercise 2" wormholes Wormholes

#include <bits/stdc++.h>
using namespace std;

int n,m,w,ins[1000005],vis[1000005],dis[1000005],fg=0,t1,t2,t3,T;
vector <pair<int,int> >g[1000005];

void dfs(int p) {
    ins[p]=1; vis[p]=1;
    for(int i=0;i<g[p].size()&&!fg; i++) {
        if(dis[g[p][i].first]>dis[p]+g[p][i].second) {
            dis[g[p][i].first]=dis[p]+g[p][i].second;
            if(ins[g[p][i].first]==0) dfs(g[p][i].first);
            else fg=1;
        }
    }
    ins[p]=0;
}

int main() {
    cin>>T;
    while(T--) {
        fg=0;
        memset(ins,0,sizeof ins);
        memset(vis,0,sizeof vis);
        memset(dis,0,sizeof dis);
        cin>>n>>m>>w;
        for(int i=1;i<=n;i++) g[i].clear();
        for(int i=1;i<=m;i++) {
            cin>>t1>>t2>>t3;
            g[t1].push_back(make_pair(t2,t3));
            g[t2].push_back(make_pair(t1,t3));
        }
        for(int i=1;i<=w;i++) {
            cin>>t1>>t2>>t3;
            g[t1].push_back(make_pair(t2,-t3));
        }
        for(int i=1;i<=n;i++) if(vis[i]==0) dis[i]=0, dfs(i);
        if(fg==1) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
}

10086. "one through 3.3 Exercise 3" Easy SSSP

#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
int dis[N],vis[N],ins[N],n,m,t1,t2,t3,flag;
vector <pair<int,int> > g[N];

void dfs(int p) {
    vis[p]=ins[p]=1;
    for(int i=0;i<g[p].size();i++) {
        int q=g[p][i].first;
        if(dis[q]>dis[p]+g[p][i].second) {
            dis[q]=dis[p]+g[p][i].second;
            if(ins[q]) {
                flag=1;
                return;
            }
            else {
                dfs(q);
            }
        }
    }
    ins[p]=0;
}

void spfa(int s) {
    memset(dis,0x3f,sizeof dis);
    memset(vis,0,sizeof vis);
    queue <int> q;
    q.push(s); dis[s]=0; vis[s]=1;
    while(!q.empty()) {
        int p=q.front(); q.pop(); vis[p]=0;
        for(int i=0;i<g[p].size();i++) {
            int x=g[p][i].first, y=g[p][i].second;
            if(dis[x] > dis[p]+y) {
                dis[x] = dis[p]+y;
                if(!vis[x]) {
                    q.push(x);
                    vis[x]=1;
                }
            }
        }
    }
    for(int i=1;i<=n;i++) {
        if(dis[i]>=0x3f3f3f3f) cout<<"NoPath"<<endl;
        else cout<<dis[i]<<endl;
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin>>n>>m;
    int s;
    cin>>s;
    for(int i=1;i<=m;i++) {
        cin>>t1>>t2>>t3;
        g[t1].push_back(make_pair(t2,t3));
    }
    for(int i=1;i<=n;i++) {
        if(vis[i]==0) {
            dfs(i);
        }
        if(flag) break;
    }
    if(flag) {
        cout<<"-1"<<endl;
    }
    else {
        spfa(s);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/mollnn/p/11621466.html
Recommended