谨以此祭奠我即将爆炸的NOIP2017.

$Mingqi\_H\ \ 2017.09.24$

Day -47

突然发现半年来自己从来没有写对过SPFA,最近几天才发现自己的板子一直是错的...赶紧找个例题修一下板子:

 1 #include<cstring>
 2 #include<cstdio>
 3 #include<queue>
 4 using namespace std;
 5 const int maxn = 1e6+10;
 6 struct Edge{
 7     int u,v,w;
 8 }edge[maxn*2];
 9 int head[maxn];
10 int cnt;
11 int dis[maxn],vis[maxn];
12 int m,n;
13 inline void add(int u,int v,int w)
14 {
15     edge[++cnt].u=head[u];
16     edge[cnt].v=v;
17     edge[cnt].w=w;
18     head[u]=cnt;
19     return;
20 }
21 void spfa(int p)
22 {
23     memset(dis,0x3f,sizeof(dis));
24     memset(vis,0,sizeof(vis));
25     int cur,nxt,v;
26     queue<int> q;
27     while(!q.empty())
28         q.pop();
29     q.push(p),vis[p]=true;
30     dis[p]=0;
31     while(!q.empty())
32     {
33         cur=q.front(),q.pop(),vis[cur]=false;
34         for(int i=head[cur];i;i=edge[i].u)
35         {
36             v=edge[i].v;
37             if(dis[p]+edge[v].w<dis[v])
38             {
39                 dis[v]=dis[p]+edge[v].w;
40                 q.push(v),vis[v]=true;
41             }
42         }
43     }
44     for(int i=1;i<=m;i++)
45         printf("%d ",dis[i]);
46     printf("\n");
47     return;
48 }
49 int main()
50 {
51     int u,v,w;
52     scanf("%d%d",&m,&n);
53     for(int i=0;i<n;i++)
54     {
55         scanf("%d%d%d",&u,&v,&w);
56         add(u,v,w);
57     }
58     for(int i=1;i<=m;i++)
59         spfa(i);
60 }

问题:学了这么久了都不会建邻接链表,SPFA加的是点,不是边,链表链表,head数组和edge数组要连起来,第一行是$edge[++cnt].u=head[u];$最后一行是$head[u]=cnt;$永远记住!!!这不是一年前了!!!

你基础不牢啊,吃枣药丸,吃枣药丸,之前还有200多天的时候,你跟现在的水平差不多啊。这100多天你干什么了?!之前不是经常拿到$Rank\ 1$吗?那个你呢?你模拟赛两次四天12道题,分数加起来还没人家一天3道题的多,你会什么啊?会数论吗?之前一直认为自己能拿到$Day2\ T1$的100分,模拟赛那么简单的一道数论题你可是一分都没拿到啊!!!该好好反思一下了!!你不会DP,也就算了,可是你连暴力也不会打,这就说不过去了吧,三四个月前建立的分类,结果到现在也没整理几个题啊,别人的Blogs都有几百道题目了啊!你总共过了有400题吗?!去重之前也仅仅有386道啊!!!还有100多道OJ上的题目,你这一年多干了些什么!

还是从板子开始吧,不能温水煮青蛙了,不能这样下去了。

Kruskal写的也不好,注意不是邻接链表了,是最最普通的数组了,不是邻接表!!!没必要写add_edge!!!写上邻接表的就错了!!!并查集也得背背啊。还有,那个sort对结构体排序还得练一练,都忘得差不多了,必要的话,重新看看OJ上的那几道题目。

#include<cstdio>
#include<algorithm>
using namespace std;
#define maxp 5005
#define maxe 200005
struct Edge{
    int u,v,w;
}edge[maxe];
inline int cmp(Edge a,Edge b){return a.w<b.w;}
int cnt;
int fat[maxp];
inline int find(int x)
{return fat[x]!=x?fat[x]=find(fat[x]):fat[x];}
inline void unionn(int x,int y)
{int fa=find(x),fb=find(y);if(fa!=fb)fat[fa]=fb;}
int n,m;
inline void Kruskal()
{
    sort(edge+1,edge+m+1,cmp);
    int k=0,ans=0;
    for(int i=1;i<=m;i++)
    {
        if(find(edge[i].u)!=find(edge[i].v))
        {
            unionn(edge[i].u,edge[i].v);
            ans+=edge[i].w;
            k++;
        }
    }
    if(k<n-1) printf("orz");
    else printf("%d",ans);
    return;
}
int main()
{
    int u,v,w;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        fat[i]=i;
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
    Kruskal();
    return 0;
}

复习计划:

NOIP范围内所有的知识点,包括数论。重点放在图论、数论、不熟练的知识点(贪心、动规、分治、二分、搜索等),时间:30d.对于其他较少考到的以及高级的内容(中高级数据结构、STL等),短期内全部不涉及,没有时间对那些较难并且没用的东西进行学习了,这不是省选前半年可以停课随便搞的时间了,毕竟马上就要考试了。

保证无论何时、无论有什么情况,每天保证至少学习1h,大周回家至少拿出2h写板子。NOIP前不再学习新的知识了。

Day-45

今天检验之前的SPFA,发现依旧不对……赶紧改过来……

 1 #include<cstdio>
 2 #include<queue>
 3 #include<cstring>
 4 #define maxn 1000001
 5 using namespace std;
 6 struct Edge
 7 {
 8     int u,v,w;
 9 } edge[2*maxn];
10 int head[maxn],cnt;
11 int n,m;
12 int vis[maxn],dis[maxn],cur,nxt;
13 inline void add(int u,int v,int w)
14 {edge[++cnt].u=head[u],edge[cnt].v=v,edge[cnt].w=w,head[u]=cnt;}
15 inline void spfa(int u)
16 {
17     queue<int>q;
18     memset(vis,0,sizeof(vis)),
19     memset(dis,0x3f,sizeof(dis)),
20     dis[u]=0;
21     while(!q.empty())q.pop();
22     vis[u]=true,q.push(u);
23     while(!q.empty())
24     {
25         cur=q.front(),vis[cur]=0,q.pop();
26         for(int i=head[cur]; i; i=edge[i].u)
27         {
28             int v=edge[i].v;
29             if(dis[v]>dis[cur]+edge[i].w)
30             {
31                 dis[v]=dis[cur]+edge[i].w;
32                 if(!vis[v])
33                     vis[v]=1,q.push(v);
34             }
35         }
36     }
37     for(int i=1; i<=m; i++)
38         printf("%d ",dis[i]);
39     printf("\n");
40     return;
41 }
42 int main()
43 {
44     int u,v,w;
45     scanf("%d%d",&m,&n);
46     for(int i=0; i<n; i++)
47     {
48         scanf("%d%d%d",&u,&v,&w);
49         add(u,v,w);
50     }
51     for(int i=1; i<=m; i++)
52         spfa(i);
53         return 0;
54 }

 ???

 1 #include<cstdio>
 2 #include<cstring>
 3 #define maxn 1000001
 4 using namespace std;
 5 struct Edge
 6 {
 7     int u,v,w;
 8 } edge[2*maxn];
 9 int head[maxn],cnt;
10 int n,m;
11 int vis[maxn],dis[maxn],cur,nxt;
12 inline void add(int u,int v,int w)
13 {edge[++cnt].u=head[u],edge[cnt].v=v,edge[cnt].w=w,head[u]=cnt;}
14 struct queue{
15     int array[4*maxn];
16     int h,t;
17     inline bool empty(){return h>=t;}
18     inline void push(int x){array[h++]=x;}
19     inline void pop(){t--;}
20     inline int front(){return array[h];}
21     inline void clear(){h=t=0;}
22 }q;
23 inline void spfa(int u)
24 {
25     memset(vis,0,sizeof(vis)),
26     memset(dis,0x3f,sizeof(dis)),
27     dis[u]=0;
28     q.clear();
29     vis[u]=true,q.push(u);
30     while(!q.empty())
31     {
32         cur=q.front(),vis[cur]=0,q.pop();
33         for(int i=head[cur]; i; i=edge[i].u)
34         {
35             int v=edge[i].v;
36             if(dis[v]>dis[cur]+edge[i].w)
37             {
38                 dis[v]=dis[cur]+edge[i].w;
39                 if(!vis[v])
40                     vis[v]=1,q.push(v);
41             }
42         }
43     }
44     for(int i=1; i<=m; i++)
45         printf("%d ",dis[i]);
46     printf("\n");
47     return;
48 }
49 int main()
50 {
51     int u,v,w;
52     scanf("%d%d",&m,&n);
53     for(int i=0; i<n; i++)
54     {
55         scanf("%d%d%d",&u,&v,&w);
56         add(v,u,w);//无向图 
57         add(u,v,w);
58     }
59     for(int i=1; i<=m; i++)
60         spfa(i);
61     return 0;
62 }
maybe手写队列???

相关文章: