• hdu 2983


    唉,这明明也是一道差不多的题目,为什么构图完之后,还是错了很久,我很不解呀,一直改,一直改,但是时间还是很慢,2766ms,SPFA+队列实现

    所以很想改一下,用栈来实现,可结果却是给了我一个TLE,无语呀,不知道怎么回事,看了大牛的很快呀,差不多500ms,用SPFA+栈实现,难道是我在预处理,构图的时候,慢了?

    不解呀?我自己的加边操作很方便,可是很慢吗?= =!

    郁闷,看来得改改习惯了

    额,都没讲下题目:

    分析题意:

    输入有两种形式:

    1:P A B X  即 B + X = A 转化一下: B - A <= -X,  A - B <= X  构造边和权:(A, B, -X), (B, A, X)

    2:V A B    即  B +1<= A 转化一下:B - A <= -1                     构造边和权:(A, B, -1) 

    先贴下我这个比较水,比较慢的代码

    #include<iostream>
    #include<string>
    #include<queue>
    #define MAXINT 9999999
    #define MAXN 1100
    using namespace std;
    int dis[MAXN],n,m,num,p[MAXN];
    int vis[MAXN],cou[MAXN];
    queue<int> Q;
    struct edge
    {
    	int v,w,next;
    	edge(int _next=0,int _v=0,int _w=0):next(_next),v(_v),w(_w){};
    }e[MAXN*201];
    bool spfa()
    {
    	for(int i=1;i<=n;i++)
    		dis[i]=0;
    	while(!Q.empty()) Q.pop();
    	for(int i=1;i<=n;i++)
    	{
    		Q.push(i);
    		vis[i]=1;
    		cou[i]=1;
    	}
    	while(!Q.empty())
    	{
    		int t=Q.front();
    		Q.pop();vis[t]=0;
    		for(int j=p[t];j!=-1;j=e[j].next)
    		{
    			if(dis[e[j].v]>e[j].w+dis[t])
    			{
    				dis[e[j].v]=e[j].w+dis[t];
    				if(!vis[e[j].v])
    				{
    					vis[e[j].v]=1;
    					cou[e[j].v]++;					
    					if(cou[e[j].v]>n)
    						return false;
    					Q.push(e[j].v);
    				}
    			}
    		}
    	}
    	return true;
    }
    int main()
    {
    	char str;
    	int a,b,c;
    	while(cin>>n>>m)
    	{
    		 num=0;
    		 memset(p,-1,sizeof(p));
    		for(int i=0;i<m;i++)
    		{
    			cin>>str;
    			if(str=='P')
    			{
    				cin>>a>>b>>c;
    				e[num]=edge(p[a],b,c);
    				p[a]=num++;
    				e[num]=edge(p[b],a,-c);
    				p[b]=num++;
    			}
    			else {
    				cin>>a>>b;
    				e[num]=edge(p[b],a,-1);
    				p[b]=num++;
    			}
    		}
    		if(spfa())
    			cout<<"Reliable"<<endl;
    		else cout<<"Unreliable"<<endl;
    	}
    	return 0;
    }
    

    看下用栈实现的代码:

    #include<stdio.h>
    #include<stdlib.h>
    #define INF 0xfffffff
    #define NN 1004
    #define MM 200004
    
    int edNum, N;
    int next[MM];
    int root[NN];
    int mark[NN];
    int cnt[NN];
    int dis[NN];
    int stack[NN];
    
    struct node{
    int e, v;
    }edge[MM];
    void add(int a, int b, int c){
    edge[edNum].e = b;
    edge[edNum].v = c;
    next[edNum] = root[a];
    root[a] = edNum++;
    }
    
    int Spfa()
    {
    int i, top, cur, tmp, nxt;
    top = 0;
    //初始化的时候没有加源点,直接将所有有根的点入栈,也很不错
    for (i = 1; i <= N; i++){
    dis[i] = INF;
    // key1
    if (root[i] != -1){
    stack[++top] = i;
    cnt[i]++;
    mark[i] = 1;
    }
    }
    
    while (top){
    cur = stack[top--];
    tmp = root[cur];
    mark[cur] = 0;
    while (tmp != -1){
    nxt = edge[tmp].e;
    //key2
    if (dis[nxt] > dis[cur] + edge[tmp].v){
    dis[nxt] = dis[cur] + edge[tmp].v;
    if (!mark[nxt]){
    cnt[nxt]++;
    if (cnt[nxt] > N + 1){
    return 1;
    }
    mark[nxt] = 1;
    stack[++top] = nxt;
    }
    }
    tmp = next[tmp];
    }
    }
    return 0;
    }
    int main()
    {
    int i, a, b, c, M;
    char str[2];
    
    while (scanf("%d%d", &N, &M) != EOF)
    {
    
    edNum = 0;
    for (i = 0; i <= N; i++){
    root[i] = -1;
    mark[i] = 0;
    cnt[i] = 0;
    }
    
    while (M--){
    scanf("%s%d%d", str, &a, &b);
    if (str[0] == 'P'){
    scanf("%d", &c);
    add(b, a, c);
    add(a, b, -c);
    }else{
    add(a, b, -1);
    }
    }
    if (Spfa()){
    puts("Unreliable");
    }else{
    puts("Reliable");
    }
    }
    return 0;
    }
    
  • 相关阅读:
    Sass
    Less文件的建立
    面试问题整理
    高光谱图像分类部分名词解析
    监督学习,无监督学习和半监督学习
    git
    node.js安装及其环境配置
    浏览器从输入网址到渲染出页面的过程
    node的api
    模块与包管理工具
  • 原文地址:https://www.cnblogs.com/nanke/p/2137679.html
Copyright © 2020-2023  润新知