谨以此祭奠我即将爆炸的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 }