//1111
//测试点二有问题
#include<bits/stdc++.h>
using namespace std;
vector<int> pred[510],pret[510],temp,temp1,ansd,anst;
int distd[510],distt[510];
int a[510][510],t[510][510],visit1[510],visit2[510];
const int inf=1000000000;
int ss,mint=inf,mins=inf;//qidm
void dfs1(int dd){
//end
if(dd==ss){
temp.push_back(dd);
int sumt=0;
for(int j=temp.size()-1;j>=1;j--){//双向
sumt=t[temp[j] ][temp[j-1] ];//双重索引又错误
}
if(sumt<mint){
mint=sumt;
ansd=temp;
}
temp.pop_back();
return;
}
temp.push_back(dd);
for(int i=0;i<pred[dd].size();i++){
dfs1(pred[dd][i]);
}
temp.pop_back();
}
void dfs2(int dd){
//end
if(dd==ss){
temp1.push_back(dd);
if(temp1.size()<mins){
mins=temp1.size();
anst=temp1;
}
temp1.pop_back();
return;
}
temp1.push_back(dd);
for(int i=0;i<pret[dd].size();i++){
dfs2(pret[dd][i]);
}
temp1.pop_back();
}
int main(){
fill(a[0],a[0]+510*510,inf);
fill(t[0],t[0]+510*510,inf);
fill(distd,distd+510,inf);
fill(distt,distt+510,inf);
int n,m,_1,_2,_3,_4,_5;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d%d%d%d",&_1,&_2,&_3,&_4,&_5);
if(_3==1){
a[_1][_2]=_4;
t[_1][_2]=_5;
}else{
a[_1][_2]=a[_2][_1]=_4;
t[_1][_2]=t[_2][_1]=_5;
}
}
int end;
scanf("%d%d",&ss,&end);
distd[ss]=0;
distt[ss]=0;
for(int i=0;i<n;i++){
int u=-1,min=inf;
for(int j=0;j<n;j++){
if(visit1[j]==0&&distd[j]<min){
min=distd[j];
u=j;
}
}
if(u==-1) break;
visit1[u]=1;
for(int v=0;v<n;v++){
if(visit1[v]==0&&a[u][v]!=inf){
if(distd[v]>distd[u]+a[u][v]){
distd[v]=distd[u]+a[u][v];
pred[v].clear();
pred[v].push_back(u);
}else if(distd[v]==distd[u]+a[u][v]){
pred[v].push_back(u);
}
}
}
}
dfs1(end);
for(int i=0;i<n;i++){
int u=-1,min=inf;
for(int j=0;j<n;j++){
if(visit2[j]==0&&distt[j]<min){
min=distt[j];
u=j;
}
}
if(u==-1) break;
visit2[u]=1;
for(int v=0;v<n;v++){
if(visit2[v]==0&&t[u][v]!=inf){
if(distt[v]>distt[u]+t[u][v]){
distt[v]=distt[u]+t[u][v];
pret[v].clear();
pret[v].push_back(u);
}else if( distt[v]==distt[u]+t[u][v]){
pret[v].push_back(u);
}
}
}
}
dfs2(end);
if(ansd==anst){
printf("Distance = %d; Time = %d:",distd[end],distt[end]);
for(int i=ansd.size()-1;i>=0;i--){
if(i!=ansd.size()-1)printf(" ->");
printf(" %d",ansd[i]);//注意一下最后有没有空格
}
}else{
printf("Distance = %d:",distd[end]);
for(int i=ansd.size()-1;i>=0;i--){
if(i!=ansd.size()-1)printf(" ->");
printf(" %d",ansd[i]);
}
printf("\n");
printf("Time = %d:",distt[end]);
for(int i=anst.size()-1;i>=0;i--){
if(i!=anst.size()-1)printf(" ->");
printf(" %d",anst[i]);
}
//printf("\n");
}
return 0;
}
//1122 先判断连不连通
#include<bits/stdc++.h>
using namespace std;
int a[500][500];
//const int inf=1000000000;
int main(){
fill(a[0],a[0]+500*500,0);//就是为了判断路径不存在的情况,每一个小栗子都要弄明白
int n,m,_1,_2;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d",&_1,&_2);
a[_1][_2]=a[_2][_1]=1;
}
int k,_3,_4;
scanf("%d",&k);
for(int i=0;i<k;i++){
scanf("%d",&_3);
int _00,_001;
set<int> num;
vector<int> path;
num.clear();
for(int j=0;j<_3;j++){
scanf("%d",&_4);
path.push_back(_4);
if(j==0) _00=_4;
if(j==_3-1) _001=_4;
num.insert(_4);
}int flag=1;
for(int i=1;i<path.size();i++){
if(a[path[i]][path[i-1]]==0){
flag=0;
break;
}
}
if(_3!=n+1) printf("NO\n");
else if(_00!=_001) printf("NO\n");
else if(num.size()!=n) printf("NO\n");
else if(flag==0) printf("NO\n");
else printf("YES\n");
}
return 0;
}
//1126
#include<bits/stdc++.h>
using namespace std;
int visit[510],n,a[510][510],dg[510];
void dfs(int index){
visit[index]=1;
for(int i=1;i<=n;i++){
if(visit[i]==0&&a[index][i]!=0){
dfs(i);
}
}
}
int main(){
int m,_1,_2;//上面已经声明过n下面又声明重复声明出错
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d",&_1,&_2);
a[_1][_2]=a[_2][_1]=1;
dg[_1]++;
dg[_2]++;
}
int cnt=0;
for(int i=1;i<=n;i++){
if(visit[i]==0){
dfs(i);
cnt++;
}
}
int even=0,odd=0;
for(int i=1;i<=n;i++){
if(dg[i]%2==0) even++;
else odd++;
if(i!=1) printf(" ");
printf("%d",dg[i]);
}
printf("\n");
if(cnt!=1) printf("Non-Eulerian");
else if(odd==2) printf("Semi-Eulerian");
else if(odd==0) printf("Eulerian");
else printf("Non-Eulerian");
return 0;
}
//1154
#include<bits/stdc++.h>
using namespace std;
struct node{
int ll,rr;
};
vector<node> a;
vector<int> b;
int main(){
int n,m,_1,_2;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d",&_1,&_2);
a.push_back({_1,_2});
}
int k,_3;
scanf("%d",&k);
for(int i=0;i<k;i++){
b.clear();
set<int>num;
for(int j=0;j<n;j++){
scanf("%d",&_3);
b.push_back(_3);
num.insert(_3);
}
int flag=1;
for(int q=0;q<a.size();q++){
if(b[a[q].ll]==b[a[q].rr]){//if多个修改项没加括号
printf("No\n");
flag=0;
break;
}
}
if(flag==1){
printf("%d-coloring\n",num.size());
}
}
return 0;
}
//1150
#include<bits/stdc++.h>
using namespace std;
const int inf=1000000000;
int a[510][510],_4;
vector<int> jm;
void dfs(int &sum){
//end
sum=0;
for(int i=1;i<_4;i++){
if(a[jm[i-1]][jm[i]]!=inf)
sum+=a[jm[i-1]][jm[i]];
else{
sum=inf;
break;
}
}
}
int main(){
fill(a[0],a[0]+510*510,inf);
int n,m,_1,_2,_3;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d%d",&_1,&_2,&_3);
a[_1][_2]=a[_2][_1]=_3;
}
int k,_5,min=inf,minindex;
scanf("%d",&k);
for(int i=1;i<=k;i++){
set<int>num;
jm.clear();
scanf("%d",&_4);
for(int j=0;j<_4;j++){
scanf("%d",&_5);//scanf 未加&
jm.push_back(_5);
num.insert(_5);
}
int len=0;
dfs(len);
if(len==inf||num.size()<n){
if(len==inf)
printf("Path %d: NA (Not a TS cycle)\n",i);
//忘了写下一段
else
printf("Path %d: %d (Not a TS cycle)\n",i,len) ;
}else if(jm[0]!=jm[jm.size()-1]){
printf("Path %d: %d (Not a TS cycle)\n",i,len);
}else if(_4>n+1){
printf("Path %d: %d (TS cycle)\n",i,len);
if(len<min){
min=len;
minindex=i;
}
}else if(_4==n+1){
printf("Path %d: %d (TS simple cycle)\n",i,len);
if(len<min){
min=len;
minindex=i;
}
}
}
printf("Shortest Dist(%d) = %d",minindex,min);
return 0;
}
//1146
#include<bits/stdc++.h>
using namespace std;
vector<int> lin[1009];
vector<int> book(1009) ,temp(1009) ;
int main(){
int n,m,_1,_2;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d",&_1,&_2);
lin[_1].push_back(_2);
book[_2]++;//对通用变量进行修改导致重复query后面出错
}
int k,_3,yu=0;
scanf("%d",&k);
for(int i=0;i<k;i++){
int flag=1;
temp=book;//引参
for(int j=1;j<=n;j++){//1--n
scanf("%d",&_3);
if(temp[_3]!=0){
flag=0;
}
if(flag==1){
for(int q=0;q<lin[_3].size();q++){
temp[lin[_3][q]]--;
}
}
}
if(flag==1) continue;
else{
if(yu!=0) printf(" ");//这么写的前提是最后一次必须输出不可能
printf("%d",i);
yu=1;//最好是让第一次不输出空格后面都输出
}
}
return 0;
}
//1142
#include<bits/stdc++.h>
using namespace std;
int book[250],a[250][250];
int main(){
int n,m,_1,_2;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d",&_1,&_2);
a[_1][_2]=a[_2][_1]=1;
}
int k,_3,_4;
scanf("%d",&k);
for(int i=0;i<k;i++){
scanf("%d",&_3);
vector<int> temp;
fill(book,book+250,0);
for(int j=0;j<_3;j++){
scanf("%d",&_4);
temp.push_back(_4);
book[_4]=1;
} int cli=1;
for(int a1=0;a1<_3;a1++){
for(int a2=a1+1;a2<_3;a2++){
if(a[temp[a1]][temp[a2]]==0){//如果上面有量没用看看是不是落了双索引
cli=0;
break;
}
}
}
if(cli==0){
printf("Not a Clique\n");
}else{ int maxcli=1;
for(int i=1;i<=n;i++){
if(book[i]==0){
int j;
for( j=0;j<temp.size();j++){
if(a[i][temp[j]]==0){
break;
}
}
if(j==temp.size()){//应该放在整个for循环外 因为我们的结束标志仅仅是最后他停在那里而不是循环一个弄一个
maxcli=0;
}
}
}
if(maxcli==0){
printf("Not Maximal\n");
}else{
printf("Yes\n");
}
}
}
return 0;
}
//1131
#include<bits/stdc++.h>
using namespace std;
map<int,int>xmindex;
int hi(vector<int>temp){//temp为存储的线路
int cnt=0;
for(int i=1;i<temp.size()-1;i++){//相当于边有标记
if(xmindex[10000*temp[i]+temp[i-1]]!=xmindex[10000*temp[i+1]+temp[i]]){
cnt++;//换乘次数
}
}
return cnt;
}
vector<int>tempp,ans,a[10000];
int minn=1000000,minhi=1000000;//所有在外面并且可能用到的都要crt 注意常数的crt 尤其是被赋值的变量
int visit[10000],endd;//终点已声明
void dfs(int qq){
//end
if(qq==endd){
visit[qq]=1;
tempp.push_back(qq);
if(tempp.size()<minn){//不适合用bfs因为bfs是一大片一大片有一个统一的度量所以可以求最短路,但是没有记录每一条特定线的前后关系,所以只适合于单标准,像这里就不能统计换乘次数
minn=tempp.size();
minhi=hi(tempp);
ans=tempp;
}else if(tempp.size()==minn){
if(hi(tempp)<minhi){
ans=tempp;
minhi=hi(tempp);
}
}
tempp.pop_back();
return;
}
tempp.push_back(qq);//doesn's name a type 层次错误
visit[qq]=1;
for(int i=0;i<a[qq].size();i++){//此时只能用for循环来卡
if(visit[a[qq][i]]==0){
dfs(a[qq][i]);//需要解封有环且无向图
visit[a[qq][i]]=0;//解封
}
}
tempp.pop_back();
}
int main(){
int n,_1,_2;
scanf("%d",&n);
vector<int> temp1[n+1];
for(int i=1;i<=n;i++){
scanf("%d",&_1);
for(int j=0;j<_1;j++){
scanf("%d",&_2);
temp1[i].push_back(_2);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<temp1[i].size();j++){
a[temp1[i][j]].push_back(temp1[i][j-1]);
a[temp1[i][j-1]].push_back(temp1[i][j]);
xmindex[10000*temp1[i][j]+temp1[i][j-1]]=i;
xmindex[temp1[i][j]+10000*temp1[i][j-1]]=i;
}
}
int k,_3;
scanf("%d",&k);
for(int i=0;i<k;i++){
scanf("%d%d",&_3,&endd);
fill(visit,visit+10000,0);
tempp.clear();
ans.clear();
minn=1000000;minhi=1000000;
dfs(_3);
int pre;
printf("%d\n",ans.size()-1);
pre=_3;
for(int i=1;i<ans.size()-1;i++){//相当于边有标记
if(xmindex[10000*ans[i]+ans[i-1]]!=xmindex[10000*ans[i+1]+ans[i]]){
printf("Take Line#%d from %04d to %04d.\n",xmindex[10000*ans[i]+ans[i-1]],pre,ans[i]);
pre=ans[i];
}
}
printf("Take Line#%d from %04d to %04d.\n",xmindex[endd*10000+ans[ans.size()-2]],pre,endd); //有可能不转站pre就一直是起点 map记得是相邻边其他的会返回0
}
return 0;
}
总结
1111第一道题两次dijkstra+dfs不知道那个测试点为啥有问题
1131 挺经典的,耗时比较多,dfs需要去标记,因为有环,注意赋值的crt
中间几个题题干中有时候隐藏起来但是需要验证的是此图的连通性
以及修改了通用变量的错误
小细节见上面的注释