codeforces Gym 101572 I 有向图最小环路径
题目链接 http://codeforces.com/gym/101572
题意 一共n个文件 存在依赖关系 根据给出的依赖关系 判断是否存在循环依赖 ,不存在的话输出SHIP IT,存在的话,打印最小的环,若有多个,输出其中任何一个。
解析 这道题其实很简单,最小的环无非就是自己到自己的最短路,直接把存在依赖的两个文件建立有向边(题意可看出),权值设为1,跑一遍Floyd,找出自己到自己最短路最小的那个点,输出它的路径。但是输入有点恶心,感觉在搞事情,处理一下就好了。
AC代码
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <iostream> 6 #include <sstream> 7 #include <algorithm> 8 #include <string> 9 #include <queue> 10 #include <map> 11 #include <vector> 12 using namespace std; 13 const int maxn = 1005; 14 const int maxm = 1e4+10; 15 const int inf = 0x3f3f3f3f; 16 const double epx = 1e-10; 17 typedef long long ll; 18 int n,m; 19 int w[maxn][maxn]; 20 int path[maxn][maxn]; 21 string s[maxn]; 22 void init() 23 { 24 for(int i=0;i<=n;i++) 25 { 26 for(int j=0;j<=n;j++) 27 { 28 w[i][j]=inf; //有向图自己到自己要初始化为inf 29 path[i][j]=j; 30 } 31 } 32 } 33 void Floyd() 34 { 35 for(int k=1;k<=n;k++) 36 for(int i=1;i<=n;i++) 37 for(int j=1;j<=n;j++) 38 if(w[i][k]!=inf&&w[k][j]!=inf) 39 { 40 int temp=w[i][k]+w[k][j]; 41 if(w[i][j]>temp) 42 { 43 w[i][j]=temp; 44 path[i][j]=path[i][k]; 45 } 46 } 47 } 48 void input() 49 { 50 cin>>n; 51 init(); 52 map<string,int> ma; 53 for(int i=1;i<=n;i++) 54 { 55 cin>>s[i]; 56 ma[s[i]]=i; //给每个文件名字编号 57 } 58 string name1,name2,imp; 59 int k; 60 for(int i=1;i<=n;i++) 61 { 62 cin>>name1>>k; //文件名,k个import 63 for(int i=0;i<k;i++) 64 { 65 cin>>imp; //import 66 getline(cin,name2); //读取import后面的字符串 直接读入了一行。。。其他操作也可以 67 string temp; 68 int j=1; 69 for(int i=1;i<name2.length();i++) //开始处理字符串 因为把import后面的空格也读进来了,所以从1开始 70 { 71 if(name2[i]==',') 72 { 73 temp=name2.substr(j,i-j); //取子串,substr(pos,n)从pos开始,截取n个字符 74 j=i+2; 75 i++; 76 int u=ma[name1],v=ma[temp]; 77 w[u][v]=1; //建单向边 78 } 79 else if(i==name2.length()-1) //最后一个单独处理 80 { 81 temp=name2.substr(j,i-j+1); 82 int u=ma[name1],v=ma[temp]; 83 w[u][v]=1; 84 } 85 } 86 //cout<<imp<<" "<<name2<<endl; 87 } 88 } 89 } 90 void print() 91 { 92 int mind=inf; 93 int sta,en; 94 for(int i=1;i<=n;i++) 95 { 96 if(w[i][i]<mind) 97 sta=en=i,mind=w[i][i]; //找最小的环 98 } 99 if(mind!=inf) 100 { 101 cout<<s[sta]; 102 int u=path[sta][en]; 103 while(u!=en) 104 { 105 cout<<" "<<s[u]; 106 u=path[u][en]; 107 } 108 cout<<endl; 109 } 110 else 111 cout<<"SHIP IT"<<endl; 112 } 113 int main() 114 { 115 input(); 116 Floyd(); 117 print(); 118 }