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 }

 

posted @ 2018-01-27 19:15  灬从此以后灬  阅读(589)  评论(0编辑  收藏  举报