csp 317号子任务

如果是弗洛伊德算法时间复杂度是0(n^3).
改成spfa算法

#include 
#include 
#include 
#include 
#include 
using namespace std;
int const N=1003;
#define INF 0x3f3f3f3f
/*7 6 2
1 0 1 0 1 1 0
1 4 1
1 2 3
2 4 4
2 3 5
2 5 7
6 7 5
*/
struct EDGE
{
    int to;
    int cost;
};
vectorG[N];
int m,n,k;
int vis[N];
int dis[N];
int mark[N];
int flag[N];
bool SPFA(int xx)
{
    for(int i = 1;i <= n;i ++)
    {
        mark[i] = 0;
        dis[i] = INF;
        vis[i] = 0;
    }
    queue q;
    q.push(xx);  //我们只需要判断负环,随便找一个起点就好
    dis[xx] = 0;
    vis[xx] = 1;//入队列
    mark[xx] ++;
    while(!q.empty())
    {
        int  u = q.front();
        q.pop();
        vis[u] = 0;//出队列
        for(int i = 0;i dis[u] + G[u][i].cost)
            {
                dis[v] = dis[u] + G[u][i].cost;
                if(!vis[v])//不在队列中的时候出队
                {
                    q.push(v);
                    mark[v] ++;
                    vis[v] = 1;
                }
                if(mark[v] >= n)//如果不存在负环,那么最多更新n-1次就可以得到最终的答案,因为一次最少更新一个节点,那么如果出现了更新n次,那么就一定出现了负环
                    return false;
            }
        }
    }
    return true;
}
int main()
{
     cin>>n>>m>>k;
     int sum;
     int jjj=0;
    memset(vis,0,sizeof(vis));
    memset(mark,0,sizeof(mark));
    memset(flag,0,sizeof(flag));
   for(int i=1;i<=n;i++)
   {
       dis[i]=INF;
   }
   for(int i=1;i<=n;i++)
   {
       int x;
       cin>>x;
       if(x==1)
       {
           flag[jjj]=i;
           jjj++;
       }

   }
    for(int i=1;i<=m;i++)
    {
        EDGE e,q;
        cin>>q.to;
        cin>>e.to;
        cin>>e.cost;
        q.cost=e.cost;
        G[q.to].push_back(e);
        G[e.to].push_back(q);
    }
    int mmm[N];
    for(int i=1;i<=n;i++)
    {
        SPFA(i);
        sum=0;
            for(int j=0;j

但还是有些错误,只有30分

你可能感兴趣的:(csp 317号子任务)